日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jvm_垃圾收集算法讲解(二)

發(fā)布時間:2024/4/13 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jvm_垃圾收集算法讲解(二) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
使用PretenureSizeThreshold可以進入指定進入老年代的對象大小,-XX:MaxTenuringThreshold這個對象經(jīng)歷多少次GC不被釋放才會進入到老年代,PretenuredSizeThreshold多大的對象是直接進入老年代,比如我設(shè)置1M,如果你超過1M的大小,那我直接給他放在老年代,是可以這么去做的,但是要注意TLAB是有限分配空間,這個參數(shù)雖然可以指定這個對象多大才可以直接進入老年代

首先我們看一下剛才配置的參數(shù)是什么意思,我的上限是1K,如果是大于1K就直接給你扔到老年代了,就不在新生代玩了,然后最大初始化都是30M,用串行垃圾收集器,打印GC的詳細信息,然后你的對象大于1K,就直接扔到老年代,new一個map,然后for循環(huán)多少次,我要for循環(huán),循環(huán)了5*1024次,然后每次去申請1M的內(nèi)存,1K肯定是大于1000的也就是我這么多次循環(huán),按理來說,這么大的數(shù)據(jù)應(yīng)該直接分配到老年代,老年代used了0%,基本都分配在新生代里了,這一塊有一個概念,其實我們現(xiàn)在開啟了一個線程,就是咱們的main線程,TLAB區(qū)會優(yōu)先分配內(nèi)存TLAB區(qū)域全稱叫做Thread Local Allocation Buffer,是本地分配的緩存,主線程本地分配緩存的東西,從名字上來看,是一個線程專用的內(nèi)存分配區(qū)域,每個內(nèi)存都有TLAB區(qū),JAVA的JDK會有一個優(yōu)化的動作,會在線程啟動的時候先配一塊獨立的內(nèi)存空間,這個空間當時沒有明確的去說,我說了你也不知道是干啥的,先讓你們有一個概念就完事了,現(xiàn)在我跟你們說,這個空間就是TLAB,線程啟動了就會有這么一個空間,來幫你做一系列的事情,幫你做優(yōu)化,這個就是Thread Local Allocation Buffer,它是為了加速對象分配而產(chǎn)生的,或者說提高線程的性能,每個線程都會產(chǎn)生TLABE區(qū),然后該線程獨享的工作區(qū)域,JAVA虛擬機使用這個中TLAB區(qū)來避免多線程沖突問題,提高了對象分配的效率,也提高了線程的性能,不要每次去取數(shù)據(jù)都去主內(nèi)存去加載,直接在我的內(nèi)存中間做就可以TLAB區(qū)一般不會特別大,當大對象無法在TLAB區(qū)的時候,才會去分配到堆上.這是JAVA的堆heap,當線程啟動的時候會有一個TLAB區(qū),一般殺雞不用宰牛刀,小對象我直接扔到TLAB玩就是了,太大了分配不了了我就直接放在堆中,放在Eden區(qū),放在s0和s1區(qū),放在老年代,默認JDK是使用TLAB區(qū)的 -XX:+UseTLAB 使用TLAB-XX:+TLABSize 設(shè)置TLAB的大小線程啟動的時候我們給TLAB分配10M,這塊還有一個特性,一般TLAB區(qū)是不需要你做任何事的,這個參數(shù)默認是有的,設(shè)置維護進入TLAB空間的單個對象的大小,我們有一個對象到底是進入JAVA堆這里,還是進入線程TLAB區(qū)中,它這個參數(shù)維護的,它是一個比值,默認是存在的,也就是整個對象如果大于1/64的話,比如我給你分配64M,整個的大小是64M,然后我的這個數(shù)據(jù)是1.1M,那這個數(shù)據(jù)就不會分配到TLAB中,而是直接放在heapJAVA堆中,新生代的Eden區(qū),這個比值是可以設(shè)置的,-XX:+PrintTLAB查看TLAB詳細信息,-XX:ResizeLAB 自動去調(diào)整TLABRefillWasterFraction的閥值,其實這些東西都是JVM提供的,不需要做任何操作,其實就是你寫代碼的時候你什么都不用干,不管這件事,但是如果有實際上的工作,如果有需求的話,如果你做一個比較核心的業(yè)務(wù)模塊,如果你做涉及到轉(zhuǎn)賬的業(yè)務(wù),這些東西你就不得不用一下,能提高一些性能,自動調(diào)節(jié)閥值,剛才的原因無非是因為不到1K的東西太小了,它會在我線程直接啟動的時候,直接進入到TLAB中了,所以我們看到老年代的參數(shù),怎么去起到作用呢,我們加上最后1行話

-XX:-UseTLAB,注意這里前面是減號,前面已經(jīng)說了加號表示啟用,減號表示禁用,禁用TLAB區(qū),強制把數(shù)據(jù)都分配到老年代,那這回我們看到了

當然這不是絕對的,大部分的數(shù)據(jù)確實都進入到了老年代了,只有非常非常細微不到1M的數(shù)據(jù)不是絕對的對象創(chuàng)建的流程圖非常細粒度的流程圖,用new關(guān)鍵字去實例化的時候,首先在棧上分配,是一個比TLAB區(qū)更提前的一個概念,這個就是保存在JAVA的Stack上了,這個使用temp變量可能會放在棧上分配,如果滿足我就放在棧上,如果失敗我就嘗試放在TLAB區(qū),滿足就放在TLAB區(qū),如果還是不滿足,判斷對象是否能進入老年代,因為這邊是把TLAB區(qū)禁用了之后,它往右邊走,去判斷-XX:PretenuredSizeThreshold=1000這個值看有沒有超過1000,超過1000就直接進入老年代,就不往新生代放了,最后整個都失敗,才放入到eden區(qū),它是一個很細粒度的流程

沒有禁用TLAB,他就就放在新生代里了,因為TLAB也是基于內(nèi)存的,你得通過-XX:PrintTLAB去打印才能看的出來

使用TLAB區(qū),加速我的方法的調(diào)用,然后這里面有PrintTLAB,然后加上PrintGC,然后給TLAB聲明一個大小,差不多100K,這個參數(shù)是自動調(diào)整大小,-XX:DoEscapeAnalysis 這是一個系統(tǒng)級的逃逸分析參數(shù),你只有把它禁用了之后它才能打印出來,TLAB這個東西是線程獨有的,通過普通的JVM是看不出來效果的,因為JVM設(shè)計到很多的東西,它都是默認開啟了,有些東西你是需要禁用的,TLAB默認是啟動的,逃逸分析參數(shù)是別把內(nèi)核的東西給屏蔽掉了,它這個詞本身就是禁用,然后設(shè)置減號就是關(guān)閉逃逸信息

現(xiàn)在是把逃逸信息給加上了

這個時候你就可以看到TLAB信息的打印了,其實這里面的參數(shù)可讀性是挺復(fù)雜的,你可以找找資料,總之最后我們把逃逸信息給禁用之后,就能看到這個結(jié)果了,如果你把這個去掉了,就看不到了TLAB的詳細信息了,它可能更快了,因為你開啟了優(yōu)化可能就更快了,但是你看不到TLAB分配空間的信息,因為他是系統(tǒng)內(nèi)核級的,他是線程內(nèi)核級的,所以說你要看到的話,正常工作的話你都不要看到這些參數(shù),配置這些參數(shù)反而性能降下去了,但是你要是看到詳細信息你就可以把它加上,這過程就可以看到打印的耗時

如果你把TLAB區(qū)禁用的話,就是設(shè)置減,線程會向主內(nèi)存去加載一些數(shù)據(jù),相對來說就比較耗時

這塊就是獨立的線程內(nèi)存空間,是對我們線程優(yōu)化是很好的,其實本質(zhì)也是屬于堆一塊的,其實這里是一個,邏輯的概念,并不是一個物理的概念,為什么分配到Eden區(qū)里了,它是一個邏輯的概念,并不是一個屋里的概念,物理的概念就是堆,無論是新生代還是老年代,反正都是堆空間,計算你開啟一個線程,你去運行,那也是用到了JAVA里的堆了,TLAB只是一個邏輯的概念,并不是說我這里有一個TLAB區(qū),它是當線程啟動的時候,JVM才會給他一塊區(qū)域,這塊區(qū)域叫TLAB,這個是一個邏輯的概念

?

總結(jié)

以上是生活随笔為你收集整理的jvm_垃圾收集算法讲解(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。