Java性能優化之針對分代垃圾回收調整
[TOC]
JVM內存的系統級的調優主要的目的是減少Minor GC的頻率和Full GC的次數,過多的Minor GC和Full GC是會佔用很多的系統資源,影響系統的吞吐量。
針對分代垃圾回收調整部分參數
- 年輕代分三個區,一個Eden區,兩個Survivor區(from和to區),可以通過
-XXSurvivorRatio
調整比例作用:默認-XX:SurvivorRatio=8,表示Survivor區與Eden區的大小比值是1:1:8,
在MinorGC過程,如果survivor空間不夠大,不能夠存儲所有的從eden空間和from suvivor空間複製過來活動對象,溢出的對象會被複制到old代,
溢出遷移到old代,會導致old代的空間快速增長。
- 大部分對象在先在Eden區中申請內存
作用:可以通過設置
-XX:PreTenureSizeThreShold
大小,令大於這個值的對象直接保存到年老代,避免在Eden區與Survivor區之間頻繁地通過複製算法回收內存 - 當Eden區滿時,無法爲新的對象分配內存時,會進行Minor GC對其回收無用對象佔用的內存,如果還有存活對象,則將存活的對象複製到Survivor From區(兩個中Survivor對稱);然後從Eden區存活下來的對象,就會被複制到From,當這個From區滿時,此區的存活對象將被複制到To區,接下來Eden區存活下來的對象就會被複制到To區,經歷一定的次數Minor GC後,還存活的對象,將被複制“年老區(Tenured)”。
作用:Minor默認15次,可通過
-MaxTenuringThreshold
參數調整年輕代回收次數,防止對象過早進入年老代,降低年老代溢出的可能性 - 年輕代和年老代的默認比例爲1:2,即年輕代佔堆內存的1/3,年老代佔2/3,可調整
-XX:NewRatio
的大小設置年輕和年老的比例。作用:默認
-XX:NewRatio=2
,即young:tenured=1:2
,適當調整年輕代大小,可以一定層度上較少Full GC出現的概率
其餘性能調優常用參數設置
-
-Xms and -Xmx (or: -XX:InitialHeapSize and -XX:MaxHeapSize)
:指定JVM的初始和最大堆內存大小,兩值可以設置相同,以避免每次垃圾回收完成後JVM重新分配內存。 -
-Xmn
:設置年輕代大小。整個堆大小=年輕代大小 + 年老代大小 + 持久代大小。所以增大年輕代後,將會減小年老代大小。此值對系統性能影響較大,Sun官方推薦配置爲整個堆的3/8。 -
-Xss
:設置每個線程的堆棧大小。JDK5.0以後每個線程堆棧大小爲1M。在相同物理內存下,減小這個值能生成更多的線程。但是操作系統對一個進程內的線程數還是有限制的,不能無限生成,經驗值在3000~5000左右。 -
-XX:+HeapDumpOnOutOfMemoryError and -XX:HeapDumpPath
:讓JVM在發生內存溢出時自動的生成堆內存快照(堆內存快照文件有可能很龐大,推薦將堆內存快照生成路徑指定到一個擁有足夠磁盤空間的地方。) -
-XX:OnOutOfMemoryError
:當內存溢發生時,我們甚至可以可以執行一些指令,比如發個E-mail通知管理員或者執行一些清理工作($ java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:OnOutOfMemoryError ="sh ~/cleanup.sh" MyApp) -
-XX:PermSize and -XX:MaxPermSize
:設置永久代大小的初始值和最大值(默認:最小值爲物理內存的1/64,最大值爲物理內存的1/16,永久代在堆內存中是一塊獨立的區域,這裏設置的永久代大小並不會被包括在使用參數-XX:MaxHeapSize 設置的堆內存大小中) -
-XX:PretenureSizeThreshold
:令大於這個設置值的對象直接在老年代分配。這樣做的目的是避免在Eden區及兩個Survivor區之間發生大量的內存複製