一、判斷對象是否存活
1、引用計數法
2、可達性分析
就是通過一系列的稱爲“GC Roots”的對象作爲起始點,從這些節點開始向下搜索,搜索所走過的路徑稱爲引用鏈(Reference Chain),當一個對象到GC Roots沒有任何引用鏈相連,則證明此對象是不可用的。
GC Root引用點:
a、JavaStack (棧楨中的本地變量表)中的引用的對象。
b、方法區中靜態引用指向的對象。
c、方法區中常量引用指向的對象。
d、Native方法中JNI引用的對象
二、回收算法
1、複製(Copying)
2、標記-清除(Mark-Sweep)
3、標記-整理(Mark-Compact)
三、安全點(Safe Point)
程序只有在到達安全點時才能暫停。安全點的選定標準是“是否具有讓程序長時間執行的特徵”。“長時間執行”的最明顯特徵就是指令序列的複用,如方法調用、循環跳轉等,具有這些功能的指令纔會產生安全點。
讓程序暫停的兩種方式:
搶先式中斷(Preemptive Suspension):在GC發生時,主動中斷所有線程,不需要線程執行的代碼主動配合。幾乎不被採用。
主動式中斷(Voluntary Suspension):設一個標誌,各個線程主動去輪詢這個標誌,遇到中斷則暫停。輪詢地方與安全點重合。
四、Full GC
從年輕代空間(包括 Eden 和 Survivor 區域)回收內存被稱爲 Minor GC,對老年代GC稱爲Major GC,而Full GC是對整個堆來說的,在最近幾個版本的JDK裏默認包括了對永生代即方法區的回收(JDK8中無永生帶了),出現Full GC的時候經常伴隨至少一次的Minor GC,但非絕對的。Major GC的速度一般會比Minor GC慢10倍以上。下邊看看有那種情況觸發JVM進行Full GC及應對策略。
1、System.gc()
此方法是建議JVM進行Full GC而非一定,但很多情況下它會觸發 Full GC,從而增加Full GC的頻率,也即增加了間歇性停頓的次數。強烈建議禁止此方法,讓虛擬機自己去管理它的內存,可通過-XX:+ DisableExplicitGC來禁止RMI調System.gc。
2、老年代空間不足
老年代空間只有在新生代對象轉入及創建大對象、大數組時纔會出現不足的現象,當執行Full GC後空間仍然不足,則拋出如下錯誤:
java.lang.OutOfMemoryError: Java heap space
3、永生區空間不足
Permanet Generation中存放的爲一些class的信息、常量、靜態變量等數據,當系統中要加載的類、反射的類和調用的方法較多時,Permanet Generation可能會被佔滿,在未配置爲採用CMS GC的情況下也會執行Full GC。如果經過Full GC仍然回收不了,那麼JVM會拋出如下錯誤信息:java.lang.OutOfMemoryError: PermGen space
4、CMS GC時出現promotion failed和concurrent mode failure
五、JAVA OPTS標準
-server
內存配置
-Xms2g -Xmx2g -Xmn768m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m
GC配置
-XX:+UseParNewGC -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrent
-XX:+UseCMSInitiatingOccupancyOnly -XX:+ScavengeBeforeFullGC -XX:CMSInitiatingOccupancyFraction=68
-XX:+CMSClassUnloadingEnabled
GC日誌配置
-XX:+PrintGCDetails -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime
-XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -Xloggc:/wls/applogs/rtlogs/server/gc.log -XX:+HeapDumpOnOutOfMemoryError
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
Dump配置
-XX:HeapDumpPath=/wls/applogs/rtlogs/server -XX:ErrorFile=/wls/applogs/rtlog/server/hs_err_pid%p.log
其他配置
-Djava.awt.headless=true -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider
-Djava.security.egd=file:/dev/./urandom -Dsun.net.inetaddr.ttl=30
-XX:SoftRefLRUPolicyMSPerMB=0
解決JDK7裏改變Sort算法的問題
-Djava.util.Arrays.useLegacyMergeSort=true
日誌配置
(同步日誌)
-Dlog4j.configurationFile=META-INF/zues/zues-log4j2-include.xml,/wls/wls81/envconfig/busrecon-service/log4j2.xml
(異步日誌)
-Dlog4j.configurationFile=META-INF/zues/zues-log4j2-async-include.xml,/wls/wls81/envconfig/busrecon-service/log4j2.xml
Dubbo配置文件
-Ddubbo.properties.file=/wls/wls81/envconfig/busrecon-service/dubbo.properties
Spring Boot特有
-Dspring.config.name=env
字符集編碼(注意,應用是UTF8的纔可以這麼寫)
-Ddefault.client.encoding=UTF-8 -Ddefault.override.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=zh -Duser.region=CN
Ref:
https://my.oschina.net/hosee/blog/674261