hz90 / java-base-knowledge

0 stars 0 forks source link

触发GC的原因memo #26

Open hz90 opened 4 years ago

hz90 commented 4 years ago

Minor GC触发条件:当Eden区满时,触发Minor GC。如果minor gc频繁可以扩充年轻代堆大小-XX:NewSize:设置年轻代大小

Full GC触发条件:

(1)调用System.gc时,系统建议执行Full GC,但是不必然执行

(2)老年代空间不足

(3)方法区空间不足

(4)通过Minor GC后进入老年代的平均大小大于老年代的可用内存

(5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

full gc stw(stop the word)时间较长

-XX:+PrintGCApplicationStoppedTime

虚拟机的解决方法就是在一些特定指令位置设置一些“安全点”,当程序运行到这些“安全点”的时候就会暂停所有当前运行的线程(Stop The World 所以叫STW),暂停后再找到“GC Roots”进行关系的组建,进而执行标记和清除。   这些特定的指令位置主要在:

1、循环的末尾 2、方法临返回前 / 调用方法的call指令后 3、可能抛异常的位置

-XX:+PrintSafepointStatistics -XX: PrintSafepointStatisticsCount=1

在stdout中会打出类似的内容:

vmop [threads: total initially_running wait_to_block]

1913.425: GenCollectForAllocation [ 55 2 0 ]

[time: spin block sync cleanup vmop] page_trap_count

[ 0 0 0 0 6 ] 0

此日志分两段,第一段是时间戳,VM Operation的类型,以及线程概况

total: 所有的java线程数 initially_running: 号召进入安全点时,还是Running状态的线程数 wait_to_block: 所有线程都不Running时,仍不是Block状态的线程数 第二段是到达安全点的各个阶段以及执行操作所花的时间,其中最重要的是vmop

spin: VMOP线程使用自旋,等待所有线程都不是Running的时间 block: VMOP线程基于锁,等待所有线程都是Block的时间 sync: spin+block +其他,这是从开始到进入安全点的总耗时 cleanup: 退出清理所用时间 vmop: 真正执行VM Operation的时间

参考 https://blog.csdn.net/qian_348840260/article/details/88819502?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase