本文主要是介绍GC-STW,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
STW
java中Stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集帮助器之外)。
Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互;这些现象多半是由于gc引起。
设置jvm参数
-Xmx512m -Xms512m -Xmn1024k -XX:+UseSerialGC -Xloggc:gc.log -XX:+PrintGCDetails
1、-XX:newSize:表示新生代初始内存的大小,应该小于-Xms的值;
2、-XX:MaxnewSize:表示新生代可被分配的内存的最大上限;当然这个值应该小于-Xmx的值;
3、-Xmn:至于这个参数则是对 -XX:newSize、-XX:MaxnewSize两个参数的同时配置,也就是说如果通过-Xmn来配置新生代的内存大小,那么-XX:newSize = -XX:MaxnewSize = -Xmn,虽然会很方便,但需要注意的是这个参数是在JDK1.4版本以后才使用的。
STW本质
情况一: 该回收的没回收
情况二: 不该回收的回收了
对于情况一: 该回收的没回收还是能忍的, 因为下次遍历时就能进行回收了
对于情况二: 不该回收的回收了是没有办法忍的, 因为明明用户逻辑还需要的对象就直接被回收了, 会导致出错.
STW本质是通过把GC和用户逻辑搞成串行的方法, 来避免上面的两种并发可能会导致的问题. 但是它引入了一个很大的代价, 就是会停止用户逻辑的运行一段时间, 举个例子, 用户逻辑是一个JAVA的网站的服务, 那么一旦它开始进行GC后就不再接受用户的请求了, 这个网站在这段时间内就是不可用(不响应任何请求)的状态. 也正是因为这个STW的特点, 让追求极致可用性的开发者都转入了C/C++阵营.
在JVM启动参数的GC参数里,多加一句:
-XX:+PrintGCApplicationStoppedTime
它就会把全部的JVM停顿时间(不只是GC),打印在GC日志里。
再多加两个参数:-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: 安全点里的总线程数
initially_running: 安全点时开始时正在运行状态的线程数
wait_to_block: 在VM Operation开始前需要等待其暂停的线程数
第二行是到达安全点时的各个阶段以及执行操作所花的时间,其中最重要的是vmop
spin: 等待线程响应
safepoint号召的时间
block: 暂停所有线程所用的时间
sync: 等于 spin+block,这是从开始到进入安全点所耗的时间,可用于判断进入安全点耗时
cleanup: 清理所用时间
vmop: 真正执行VM Operation的时间
JVM里需要STW的情况有下面几种
垃圾收集停顿时间
代码反优化
刷新代码缓存类重定义(例如热插拔或插装)
偏向锁撤销
各种调试操作(例如:死锁检查或堆栈跟踪转储)
4 引发长时间STW的Troubleshooting
引发STW时间过长的原因答主能确定的有如下几个:
Full GC因为GC的时间算在STW里面。建议优化GC缩短STW时间。
RevokeBias 通过分析STW日志,发现有时候撤销偏向锁操作也会消耗很长时间。在高并发系统中 建议禁用偏向锁还有一个引发长时间的STW 原因是因为程序中存在非常长的Count Looop并且循环中没有执行其他函数,或者执行的函数被内联进来。这种程序会导致Spin 的时间变的很长,JVM要等待程序运行
程序中存在非常长的Count Looop并且循环中没有执行其他函数,或者执行的函数被内联进来。这种程序会导致Spin的时间变的很长
加上了 -XX:NewRatio=2 了,GC看起来平滑了N倍
STW相关参数
3.1 -XX:+PrintGCApplicationStoppedTime
这个参数用于记录程序运行期间所有情况引发的STW
3.2-XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1
这两个参数用于记录STW发生的原因、线程情况、STW各个阶段的停顿时间等。当添加这两个参数后,程序运行期间会打印如下内容
参数介绍:
vmop:引发STW的原因,以及触发时间,本例中是GC。该项常见的输出有:RevokeBias、BulkRevokeBias、Deoptimize、G1IncCollectionPause。数字306936.812是虚拟机启动后运行的秒数。GC log可以根据该项内容定位Total time for which application threads…引发的详细信息。
total :STW发生时,JVM存在的线程数目。
initially_running :STW发生时,仍在运行的线程数,这项是Spin阶段的 时间来源
wait_to_block : STW需要阻塞的线程数目,这项是block阶段的时间来源
spin,block,cleanup,vmop前面已经做了介绍,sync=spin + block + 其他。
这篇关于GC-STW的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!