JVM调优之StringTable调优
创始人
2024-03-15 04:38:39

jdk1.8之后,JVM内存结构如下

 所谓的StringTable,即字符串常量池(以下简称串池),存放在堆内存中。

 我们先介绍一下intern方法

String s = "ab";
//将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池,会把串池中的对象返回
String s2 = s.intern(); 

调优方法1.因为StringTable是由HashTable实现的,所以可以适当增加HashTable桶的个数,来减少字符串放入串池所需要的时间。

示例代码:遍历文本文件,读取每一行的内容放入串池

public class Demo1_24 {public static void main(String[] args) throws IOException {try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("linux.words"), "utf-8"))) {String line = null;long start = System.nanoTime();while (true) {line = reader.readLine();if (line == null) {break;}line.intern();}System.out.println("cost:" + (System.nanoTime() - start) / 1000000);}}
}

linux.words是存放文本的文件(实际文本有四百多万行,只粘贴部分做示例)

1080
10-point
10th
11-point
12-point
16-point
18-point
1st
2
20-point
2,4,5-t
2,4-d
2D
2nd
30-30
3-D
3-d
3D
3M
3rd
48-point
4-D
4GL
4H
4th
5-point
5-T
5th
6-point
6th
7-point
7th
8-point
8th
9-point
9th
-a
A
A.
a
a'
a-
a.
A-1
A1
a1
A4
A5
AA
aa

我们运行程序,发现耗时不到1s

 然后我们设置JVM运行参数,修改桶的数量为1009,再次运行

-XX:+PrintStringTableStatistics -XX:StringTableSize=1009

 

 运行结果耗时8秒 如下图

 StringTable默认的桶的数量是60013,当桶的数量设置变小,哈希碰撞的概率增加,链表长度

 变长,数据插入就会变慢,可以适当增加HashTable桶的个数,来减少字符串放入串池所需要的时间。

调优方法2:如果应用里有大量的字符串,而且字符串可能存在重复的问题,可以通过intern方法让字符串入池,减少字符串个数(触发垃圾回收 没入池的字符串被回收掉),节约堆内存的使用

示例代码:同样是遍历上述的文本文件,将每一行的内容放入ArrayList中,循环操作10次

public class Demo1_25 {public static void main(String[] args) throws IOException {List address = new ArrayList<>();System.in.read();for (int i = 0; i < 10; i++) {try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("linux.words"), "utf-8"))) {String line = null;long start = System.nanoTime();while (true) {line = reader.readLine();if(line == null) {break;}address.add(line);}System.out.println("cost:" +(System.nanoTime()-start)/1000000);}}System.in.read();}
}

运行以上代码,我们控制台输入

jvisualvm 

查看字符串所占用的内存使用情况 

然后我们敲下Enter执行我们的主程序,遍历文本文件,发现内存占用飙高很多

 

 然后我们修改代码(只改了一行代码,address.add(line.intern())

public class Demo1_25 {public static void main(String[] args) throws IOException {List address = new ArrayList<>();System.in.read();for (int i = 0; i < 10; i++) {try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("linux.words"), "utf-8"))) {String line = null;long start = System.nanoTime();while (true) {line = reader.readLine();if(line == null) {break;}//仅修改这一处代码address.add(line.intern());}System.out.println("cost:" +(System.nanoTime()-start)/1000000);}}System.in.read();}
}

 再运行查看内存占用情况,下降了很多

 我们循环遍历10次,会在堆中产生很多重复的字符串,而ArrayList中存放的对象都来自串池,堆中的字符串 如果没被引用,会被垃圾回收掉,从而节约了堆内存的使用

相关内容

热门资讯

应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...