淺談java內存分配和回收策略_第1頁
淺談java內存分配和回收策略_第2頁
淺談java內存分配和回收策略_第3頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

?、導論java技術體系中所提到的內存?動化管理歸根結底就是內存的分配與回收兩個問題,之前已經和?家談過java回收的相關知識,今天來和?家聊聊java對象的在內存中的分配。通俗的講,對象的內存分配就是在堆上的分配,對象主要分配在新?代的Eden上(關于對象在內存上的分代在垃圾回收中會補上,想了解的也可以參考《深?理解java虛擬機》),如果啟動了本地線程分配緩沖,講按線程優先在TLAB上分配。少數情況下也是直接在?年代中分配。?、經典的分配策略1、對象優先在Eden上分配?般情況下對象都是優先分配在Eden上,當Eden沒有?夠的空間進?分配時,jvm會發起?次Minor。如果還是沒有?夠的空間分配,后?還有另外的措施,下?會提到。設置虛擬機的偶記?志參數-XX:+PrintGCDetails,在垃圾回收的時候會打印內存的回收?志,并且在進程退出的時候會輸出當前內存各區域的分配情況。下?來看下具體的例?,?先需要設置jvm的參數-Xms20m-Xmx20m-Xmn10m,這三個參數說明java堆??為20M,且不可擴展,其中10M分配給新?代,剩下的10M分配給?年代。-XX:SurvivorRatio=8是jvm默認的新?代中Eden和Survivor?例,默認為8:1。原因是新?代中的對象98%都會在下?次GC的時候回收掉,所以很適合采?復制算法進?垃圾回收,所以新?代10M的內存中,8M是Eden,1M是Survivor,另外的1M是未使?配合復制算法的內存塊,也是Survivor。1publicclassReflectTest{234privatestaticfinalint_1MB=1024*1024;5publicstaticvoidtestAllocation(){byte[]allocation1,allocation2,allocation3,allocation4;allocation1=newbyte[2*_1MB];allocation2=newbyte[2*_1MB];allocation3=newbyte[2*_1MB];allocation4=newbyte[6*_1MB];}67891011121314151617}publicstaticvoidmain(String[]args){ReflectTest.testAllocation();}輸出如下HeapPSYoungGentotal9216K,used6651K[0x000000000b520000,0x000000000bf20000,0x000000000bf20000)edenspace8192K,81%used[0x000000000b520000,0x000000000bb9ef28,0x000000000bd20000)fromspace1024K,0%used[0x000000000be20000,0x000000000be20000,0x000000000bf20000)tospace1024K,0%used[0x000000000bd20000,0x000000000bd20000,0x000000000be20000)PSOldGenobjectspace10240K,60%used[0x000000000ab20000,0x000000000b120018,0x000000000b520000)PSPermGentotal21248K,used2973K[0x0000000005720000,0x0000000006be0000,0x000000000ab20000)total10240K,used6144K[0x000000000ab20000,0x000000000b520000,0x000000000b520000)objectspace21248K,13%used[0x0000000005720000,0x0000000005a07498,0x0000000006be0000)可以看到eden占?了81%,說明allocation1,allocation2,allocation3都是分配在新?代Eden上。2、?對象直接分配在?年代上?對象是指需要?量連續內存空間去存放的對象,類似于那種很長的字符串和數組。?對象對于虛擬機的內存分布來講并不是好事,當遇到很多存活僅?輪的?對象jvm更加難處理,寫代碼的時候應該避免這樣的問題。虛擬機中提供了-XX:PretenureSizeThreshold參數,另?于這個值的對象直接分配到?年代,這樣做的?的是為了避免在Eden區和Survivor區之間發??量的內存copy,在之前講過的垃圾回收算法復制算法有提到過,就不多說了。publicclassReflectTestBig{privatestaticfinalint_1MB=1024*1024;publicstaticvoidtestAllocation(){byte[]allocation2,allocation3,allocation4;allocation2=newbyte[2*_1MB];allocation3=newbyte[2*_1MB];allocation4=newbyte[6*_1MB];}publicstaticvoidmain(String[]args){ReflectTestBig.testAllocation();}}輸出如下HeapPSYoungGentotal8960K,used4597K[0x000000000b510000,0x000000000bf10000,0x000000000bf10000)edenspace7680K,59%used[0x000000000b510000,0x000000000b98d458,0x000000000bc90000)fromspace1280K,0%used[0x000000000bdd0000,0x000000000bdd0000,0x000000000bf10000)tospace1280K,0%used[0x000000000bc90000,0x000000000bc90000,0x000000000bdd0000)PSOldGenobjectspace10240K,60%used[0x000000000ab10000,0x000000000b110018,0x000000000b510000)PSPermGentotal21248K,used2973K[0x0000000005710000,0x0000000006bd0000,0x000000000ab10000)total10240K,used6144K[0x000000000ab10000,0x000000000b510000,0x000000000b510000)objectspace21248K,13%used[0x0000000005710000,0x00000000059f7460,0x0000000006bd0000)可以看到allocation4已經超過了設置的-XX:PretenureSizeThreshold=3145728,隨意allocation4直接被分配到了?年代,?年代占?率為60%。注意這?設置-XX:PretenureSizeThreshold=3145728不能寫成-XX:PretenureSizeThreshold=3m,否則jvm將?法識別。3、長期存活的對象將進??年代虛擬機既然采?了分帶收集的思想來管理內存,那內存回收就必須識別哪些對象應該放在新?代,哪些對象應該放在?年代。為了打到?的,jvm給每個對象定義了?個年齡計數器(Age)。如果對象在Eden出?并且能過第?次Minor后仍然存活,并且可以在Survivor存放的話,將被移動到Survivor中,并將對象的年齡設為1。對象每躲過?次Minor,年齡就會加1,當他的年齡超過?年的閾值的時候,該對象就會晉升到?年代。這個閾值jvm默認是15,可以通過-XX:MaxTenuringThreshold來設置。publicclassJavaTest{staticintm=1024*1024;publicstaticvoidmain(String[]args){byte[]a1=newbyte[1*m/4];byte[]a2=newbyte[7*m];byte[]a3=newbyte[3*m];//GC}}輸出如下[GC[DefNew:7767K->403K(9216K),0.0062209secs]7767K->7571K(19456K),0.0062482secs][Times:user=0.00sys=0.00,real=0.01secs]a3okHeapdefnewgenerationtotal9216K,used3639K[0x331d0000,0x33bd0000,0x33bd0000)edenspace8192K,39%used[0x331d0000,0x334f9040,0x339d0000)fromspace1024K,39%used[0x33ad0000,0x33b34de8,0x33bd0000)tospace1024K,0%used[0x339d0000,0x339d0000,0x33ad0000)tenuredgenerationtotal10240K,used7168K[0x33bd0000,0x345d0000,0x345d0000)thespace10240K,70%used[0x33bd0000,0x342d0010,0x342d0200,0x345d0000)compactingpermgentotal12288K,used381K[0x345d0000,0x351d0000,0x385d0000)thespace12288K,3%used[0x345d0000,0x3462f548,0x3462f600,0x351d0000)rospace10240K,55%used[0x385d0000,0x38b51140,0x38b51200,0x38fd0000)rwspace12288K,55%used[0x38fd0000,0x396744c8,0x39674600,0x39bd0000)可以看到a2已經存活了?次,年齡為1,滿?所設置的-XX:MaxTenuringThreshold=1,所以a2進?了?年代,?a3則進?了新?代。4、動態對象年齡判定為了能更好的適應不同程序的內存狀態,虛擬機并不總是要求對象的年齡必須達到-XX:MaxTenuringThreshold所設置的值才能晉升到?年代,如果在Survivor空間中相同年齡所有對象??的總和?于Survivor空間的?半,年齡?于或等于該年齡的對象就可以直接進??年區,?須達到-XX:MaxTenuringThreshold中的設置值。5、空間分配擔保在發?Minor的時候,虛擬機會檢測每次晉升到?年代的平均??是否?于?年代的剩余空間,如果?于,則直接進??次FUllGC。如果?于,則查看HandlerPromotionFailyre設置是否允許擔保失敗,如果允許那就只進?Minor,如果不允許則也要改進?次FUllGC。也就是說新?代Eden存不下改對象的時候就會將該對象存放在?年代。三、常?的參數設置1、-Xms:初始堆??,默認(MinHeapFreeRatio參數可以調整空余堆內存?于40%時,JVM就會增?堆直到-Xmx的最?限制。2、Xmx:最?堆??,默認(MaxHeapFreeRatio參數可以調整空余堆內存?于70%時,JVM會減少堆直到的最?限制。3、-Xmn:年輕代??(1.4orlator),此處的??是(eden+2survivor與jmap-heap中顯?的Newgen是不同的。整個堆??年輕代??+年?代??+持久代??。增?年輕代后將會減?年?代??此值對系統性能影響較?,Sun官?推薦配置為整個堆的3/8。4、-XX:NewSize:設置年輕代??(for1.3/1.4)。5、-XX:MaxNewSize:年輕代最?值(for1.3/1.4)。6、-XX:PermSize:設置持久代(perm初始值。7、-XX:MaxPermSize:設置持久代最?值。8、-Xss:每個線程的堆棧??,JDK5.0以后每個線程堆棧??為以前每個線程堆棧??為256K.更具應?的線程所需內存??進?調整在相同物理內存下減?這個值能?成更多的線程但是操作系統對?個進程內的線程數還是有限制的不能?限?成經驗值在3000~5000左右。9、-XX:NewRatio:年輕代包括Eden和兩個Survivor區與年?代的?值除去持久代,-XX:NewRatio=4表?年輕代與年?代所占?值為年輕代占整個堆棧的1/5。Xms=Xmx并且設置了Xmn的情況下,該參數不需要進?設置。10、-XX:SurvivorRatio:Eden區與Survivor區的???值,設置為則兩個Survivor區與?個Eden區的?值為?個Survivor區占整個年輕代的1/10。11、-XX:L

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論