jdk1.8之后,JVM內(nèi)存結(jié)構(gòu)如下
創(chuàng)新互聯(lián)公司致力于網(wǎng)站制作、網(wǎng)站建設(shè),成都網(wǎng)站設(shè)計,集團(tuán)網(wǎng)站建設(shè)等服務(wù)標(biāo)準(zhǔn)化,推過標(biāo)準(zhǔn)化降低中小企業(yè)的建站的成本,并持續(xù)提升建站的定制化服務(wù)水平進(jìn)行質(zhì)量交付,讓企業(yè)網(wǎng)站從市場競爭中脫穎而出。 選擇創(chuàng)新互聯(lián)公司,就選擇了安全、穩(wěn)定、美觀的網(wǎng)站建設(shè)服務(wù)!所謂的StringTable,即字符串常量池(以下簡稱串池),存放在堆內(nèi)存中。
我們先介紹一下intern方法
String s = "ab";
//將這個字符串對象嘗試放入串池,如果有則并不會放入,如果沒有則放入串池,會把串池中的對象返回
String s2 = s.intern();
調(diào)優(yōu)方法1.因為StringTable是由HashTable實現(xiàn)的,所以可以適當(dāng)增加HashTable桶的個數(shù),來減少字符串放入串池所需要的時間。
示例代碼:遍歷文本文件,讀取每一行的內(nèi)容放入串池
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
我們運行程序,發(fā)現(xiàn)耗時不到1s
然后我們設(shè)置JVM運行參數(shù),修改桶的數(shù)量為1009,再次運行
-XX:+PrintStringTableStatistics -XX:StringTableSize=1009
運行結(jié)果耗時8秒 如下圖
StringTable默認(rèn)的桶的數(shù)量是60013,當(dāng)桶的數(shù)量設(shè)置變小,哈希碰撞的概率增加,鏈表長度
變長,數(shù)據(jù)插入就會變慢,可以適當(dāng)增加HashTable桶的個數(shù),來減少字符串放入串池所需要的時間。
調(diào)優(yōu)方法2:如果應(yīng)用里有大量的字符串,而且字符串可能存在重復(fù)的問題,可以通過intern方法讓字符串入池,減少字符串個數(shù)(觸發(fā)垃圾回收 沒入池的字符串被回收掉),節(jié)約堆內(nèi)存的使用
示例代碼:同樣是遍歷上述的文本文件,將每一行的內(nèi)容放入ArrayList中,循環(huán)操作10次
public class Demo1_25 {
public static void main(String[] args) throws IOException {
Listaddress = 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?
查看字符串所占用的內(nèi)存使用情況?
然后我們敲下Enter執(zhí)行我們的主程序,遍歷文本文件,發(fā)現(xiàn)內(nèi)存占用飆高很多
然后我們修改代碼(只改了一行代碼,address.add(line.intern())
public class Demo1_25 {
public static void main(String[] args) throws IOException {
Listaddress = 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();
}
}
再運行查看內(nèi)存占用情況,下降了很多
我們循環(huán)遍歷10次,會在堆中產(chǎn)生很多重復(fù)的字符串,而ArrayList中存放的對象都來自串池,堆中的字符串 如果沒被引用,會被垃圾回收掉,從而節(jié)約了堆內(nèi)存的使用
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
文章名稱:JVM調(diào)優(yōu)之StringTable調(diào)優(yōu)-創(chuàng)新互聯(lián)
文章來源:http://bm7419.com/article20/dpdejo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、網(wǎng)站收錄、軟件開發(fā)、標(biāo)簽優(yōu)化、微信小程序、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容