JVM調(diào)優(yōu)之StringTable調(diào)優(yōu)-創(chuàng)新互聯(lián)

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)

手機網(wǎng)站建設(shè)