jvm 查看这篇文章: https://www.dutycode.com/jvm_xmx_xmn_xms_shezhi.html
X指的是FULLGC后的老年代空间大小。总xmx设置为 1.5X + 3X一般即可。年轻带占据总共的3/8.
查看FULLGC:
在java的启动日志中加入gc日志,这样运行1-2天查看fullgc后的空间。
-verbose:gc
或 -XX:+PrintGC
-XX:+PrintGCDetails 在高版本不推荐使用,在高版本建议用-Xloggc:gc.log
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/work/log/dump -verbose:gc
-XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps
-Xloggc:/home/work/log/gc.log
也可以通过以下命令直接查看,但是强制 FULLGC会阻止应用服务的,一般不要使用。
gc会处理年轻代,fullgc会处理年轻代,年老带和永久区
>jstat -gcutil [pid] [timemill] [count]
YGC:表示年轻代回收GC的次数,YGCT表示回收花费的总时长,YGCT/YGC=单次时长
FGC:表示全回收GC的次数,FGCT表示全回收花费的总时长 FGCT/FGC=单次时长
GCT:是采样的间隔时间10.8,即GC每10.8S启动一次
>jstat -class [pid] //查看类加载情况
>jstat -compiler [pid] //查看类编译情况
> jstat -gc [pid] [looptime] //查看gc回收
线程查看:
> top -Hp [pidA]
>jstack [pid] > error.txt
>jstack -F [pid]
>printf "%x\n" [pid] //获取16进制的值 pidB
> jstack -F [pid] |grep [pidB]
jmap -dump:file=[filepath_name] [pid]
》jmap -dump:live,format=b,file=heap.bin <pid> 将当前的存活对象dump到文件,此时会触发FullGC
》jmap -histo:live <pid> 打印每个class的实例数目,内存占用,类全名信息.live子参数加上后,只统计活的对象数量. 此时会触发FullGC
系统的内存设置的紧促,会加快gc的回收,且单次gc使用时间会变短。当内存紧促时,可以这样调整。
内存多时,尽量多的赋予内存,这样gc的回收次数会减少,但是每次回收的时间会加长。对于非低延时应用可以采用。
gc回收触发动机:
Minor GC是新生代GC(内部分为:Eden伊甸园,Suvive幸存区), Major GC/Full GC
minor gc 触发: 当建立一个对象无法创建时,即年轻代-Eden空间不足,会触发gc。
fullGC:1. 当老年代的内存不足时,会触发。 2. 当Eden,fromSpace-》toSpace空间不足时,直接写入到老年代中,且对象很大,可能会触发。
3.Minor GC后进入老年代的平均大小大于老年代的可用内存.
一般对象清理,要进行寻址,寻址为空2次的,才执行finalize()方法释放。
程序手动触发,但是是建议,一般处理大数据信息获取等可以执行。
》System.gc
常用jvm设置:
java -Xloggc:/log/gc.log -version //查看默认gc设置
1. UseParallelGC (jdk8默认)
java -Xmx2g -Xms2g -Xss256K -Xmn1g -XX:+UseParallelGC -XX:ParallelGCThreads=4 -XX:MaxGCPauseMillis=50 -XX:+UseAdaptiveSizePolicy -Xloggc:/log/gc.log
2. UseG1GC (jdk9之后变为默认)
java -Xmx4g -Xms4g -Xss256K -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:+ParallelRefProcEnabled -XX:+UnlockExperimentalVMOptions -XX:+DoEscapeAnalysis -XX:ParallelGCThreads=4 -XX:ConcGCThreads=1 -XX:+DisableExplicitGC -Xloggc:/log/gc.log
说明:
-XX:MaxGCPauseMillis=20 // 默认值是努力控制在200ms,当应用要求低延时时,可以调整此值
-Xmx4g -Xms4g 决定内存初始和最大占用内存,内存占用过大会导致垃圾回收周期变长,而每次要回收的垃圾变多,增加延时。
-XX:G1HeapRegionSize
参数允许你指定这些区域的大小,该值可在 1MB 到 32MB 之间(必须是 2 的幂)。区域大小会直接影响 G1 收集器的性能;例如,有更多的小区域可能会增加维护区域之间数据结构的开销,而较大的区域可能会导致内存利用率降低。
设置此参数时需要仔细考虑,因为它会影响以下几点:
- 垃圾回收停顿时间:较小的区域可能会导致更频繁的垃圾回收,而较大的区域可能会增加每次垃圾回收的停顿时间。
- 堆内存的利用率:如果设置的区域太大,可能会造成内存浪费,因为每个区域内未使用到的内存空间不能用于其他区域。
- 收集器的预测性能:G1 收集器会根据停顿时间目标(Pause Time Goal)来选择回收的区域个数,区域大小的配置会影响到这一预测的准确性。
默认情况下,G1会根据堆的大小自动选择区域的大小。只有当需要根据具体应用的性能需求调整回收行为时,才需要手动设置这个参数。在大多数情况下,让 G1 自动管理这些大小是最佳的选择。如果你确定需要手动设置 G1HeapRegionSize
,建议进行彻底的测试,以确保任何改变都会带来性能的提升。
3. CMSGC (jdk14被放弃)
java -Xmx4g -Xms4g -Xss256K -Xmn2g -XX:+UseConcMarkSweepGC -XX:MaxGCPauseMillis=20 -XX:ParallelGCThreads=4
cms在jdk9版本被废弃,在jdk14彻底被移除,默认使用G1GC代替
4. ZGC
JDK15 开始有个实验版本ZGC,但是不是默认的。ZGC对系统有要求必须是64位系统。
-XX:+UseZGC
5. 容器化应对:
在 java version "1.8.0_191" 版本以上支持cgroup,用于感知容器,防止内存占用超额。在低版本中因无法感知容器内存,而实际使用却看的是容器下的宿主机。
-XX:+UseContainerSupport -XX:MinRAMPercentage=80.0 -XX:MaxRAMPercentage=80.0 -XX:InitialRAMPercentage=80.0