Java-JConsole
概念
volatile
能禁止指令重排序,所以 volatile 能在一定程度上保证有序性
年轻代
Eden
Survivor
老年代
Tenured:1. 回收多次回收不了的 2. 大对象
GC
垃圾
没有任何引用指向的对象或多个对象「循环引用」
定位垃圾算法
引用计数「Reference Count」
根可达算法「Root Searching」
GC Roots:线程栈变量、静态变量、常量池、JNI 指针、Class 对象
回收算法
- Mark-Sweep「标记清除」——位置不连续、产生碎片
- 拷贝算法:没有碎片、浪费空间
- 标记压缩「Mark Compact」:没有碎片、效率偏低
JVM 分代算法
- 部分垃圾回收器使用的模型
- 新生代+老年代+永久代「1.7」/元数据区「1.8」Metaspace
- 永久代/元数据——Class 对象
- 永久代必须设定大小限制,元数据可以设置,也可以不设置,无上限
- 字符串常量 1.7-永久代,1.8-堆
- MethodArea 逻辑概念-永久代「1.7」、元数据「1.8」
- 新生代 = Eden + 2个 Survivor区
- YGC:复制算法,大多数对象被回收,活的进入 Survivor「S0」
- 再次 YGC,活着的对象 Eden+S0 -> S1
- 再次 YGC,Eden+S1->S0
- 年龄足够->老年代
- S 区装不下->老年代
- 老年代
- 顽固分子
- 老年代满了,FGC,耗时
- GC Tuning
- 尽量减少 FGC
- MinorGC=YGC
- MajorGC=FGC
垃圾回收器
- Serial——年轻代,串型回收
- Parallel Scavenge 年轻代,并行回收
- ParNew 年轻代,配合 CMS 并行回收
- SerialOld
- ParallelOld
- CMS「ConcurrentMarkSweep」老年代,并发,垃圾回收和应用同时运行,降低 STW「200ms」
- G1「10ms」
- ZGC「1ms」 PK C++
- Shenandoah
- Eplison
- JDK 1.8默认垃圾回收器:PS + ParallelOld
调优参数
参数值(最终生效值)
1
--XX:+PrintFlagsFinal
参数值(默认)
1
--XX:+PrintFlagsInitial
命令行参数
1
-XX:+PrintCommandLineFlags
G1
追求响应时间
- XX:MaxGCPauseMillis 200
- 对 STW进行控制
灵活
- 分 Region 回收
- 优先回收花费时间少、垃圾比例高的 Region
手工指定 Region 大小
XX:G1HeapRegionSize
工作原理
- 初始标记——根对象直接引用的对象
- 并发标记——根追踪算法,不打断应用运行,会监视应用运行
- 最终标记——
- 并行回收「复制回收」
优化
1 | -XX:+UseG1GC |
参数
堆大小 = 年轻代大小(eden) + 年老代大小(old) + 2 个持久代大小(survivor)
参数名称 | 含义 | 默认值 | |
---|---|---|---|
-Xms | 初始堆大小 | 物理内存的 1/64 (<1GB) | 默认 (MinHeapFreeRatio 参数可以调整) 空余堆内存小于 40% 时,JVM 就会增大堆直到 - Xmx 的最大限制. |
-Xmx | 最大堆大小 | 物理内存的 1/4 (<1GB) | |
-Xss | 每个线程的堆栈大小 | JDK5.0 以后每个线程堆栈大小为 1M, 以前每个线程堆栈大小为 256K. 更具应用的线程所需内存大小进行 调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在 3000~5000 左右 一般小的应用, 如果栈不是很深, 应该是 128k 够用的 大的应用建议使用 256k。这个选项对性能影响比较大,需要严格的测试。(校长) 和 threadstacksize 选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:”” -Xss is translated in a VM flag named ThreadStackSize” 一般设置这个值就可以了。 |
|
-Xmn | 年轻代大小 (1.4or lator) | eden + 2 survivor space | PS Eden Space + PS Survivor Space*2 |
-XX:SurvivorRatio | Eden 区与 Survivor 区的大小比值 | 设置为 8, 则两个 Survivor 区与一个 Eden 区的比值为 2:8, 一个 Survivor 区占整个年轻代的 1/10 | |
-XX:PermSize | 设置持久代 (perm gen) 初始值 | 物理内存的 1/64 | |
-XX:MaxPermSize | 设置持久代最大值 | 物理内存 的 1/4 | |
-XX:NewRatio | 年轻代 (包括 Eden 和两个 Survivor 区) 与年老代的比值 (除去持久代) | -XX:NewRatio=4 表示年轻代与年老代所占比值为 1:4, 年轻代占整个堆栈的 1/5 Xms=Xmx 并且设置了 Xmn 的情况下,该参数不需要进行设置。 |
工具路径
JDK 自带 JVM 监测工具路径示例: C:\Program Files\Java\jdk1.8.0_191\bin\
JConsole
jconsole.exe
本地进程
远程进程
Tomcat
Linux
catalina.sh
1
2
3
4JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=192.168.0.110 -Dcom.sun.management.jmxremote"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.port=9000"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.ssl=false"Windows
catalina.bat
1
2
3
4set JAVA_OPTS=-Djava.rmi.server.hostname=192.168.0.110 -Dcom.sun.management.jmxremote
set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.management.jmxremote.port=9000
set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.management.jmxremote.authenticate=false
set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.management.jmxremote.ssl=false
SpringBoot
1
java -server -Xms512m -Xmx768m -jar -Djava.rmi.server.hostname=10.211.55.3 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9000 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false files-0.0.1-SNAPSHOT.jar
jvisualvm
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 王文哲的博客!