Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java挂起几秒钟,但在gc日志中未找到gc暂停_Java_Linux_Garbage Collection_G1gc - Fatal编程技术网

Java挂起几秒钟,但在gc日志中未找到gc暂停

Java挂起几秒钟,但在gc日志中未找到gc暂停,java,linux,garbage-collection,g1gc,Java,Linux,Garbage Collection,G1gc,我有一个java应用程序在Linux(CentOS 7)上运行,使用g1 gc,它经常挂起几秒钟,看起来就像gc暂停一样,但我在gc日志中找不到这么长的暂停 为了确保java应用程序挂起,我启动了一个后台线程,该线程只需每隔500毫秒打印一次日志。发现日志暂停了几秒钟。这是日志,它在[14:31:02834]到[14:31:05677] WARN [2018-07-16 14:30:57,831][clock]py.datanode.DataNodeAppEngine(196):tick...

我有一个java应用程序在Linux(CentOS 7)上运行,使用g1 gc,它经常挂起几秒钟,看起来就像gc暂停一样,但我在gc日志中找不到这么长的暂停

为了确保java应用程序挂起,我启动了一个后台线程,该线程只需每隔500毫秒打印一次日志。发现日志暂停了几秒钟。这是日志,它在[14:31:02834][14:31:05677]

WARN [2018-07-16 14:30:57,831][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:30:58,331][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:30:58,832][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:30:59,332][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:30:59,832][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:31:00,333][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:31:00,833][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:31:01,333][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:31:01,834][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:31:02,334][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:31:02,834][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:31:05,677][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:31:06,177][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:31:06,678][clock]py.datanode.DataNodeAppEngine(196):tick...
WARN [2018-07-16 14:31:07,178][clock]py.datanode.DataNodeAppEngine(196):tick...
和gc日志(grep,其中包含停止应用程序线程的总时间):

此外,这个java进程还有一些线程运行本机代码,它们是用C编写的,不受jvm的影响。这些线程运行得很好,我很确定这是因为其中一个线程是心跳线程,心跳超时为800MS,但在暂停期间没有发现心跳超时

我还监控了cpu的使用情况,12核cpu的空闲率高达80%

内存使用率也不太高,THP(透明巨大页面)和交换内存也被禁用

我发现有一件事我不明白:

在暂停附近总是有一个并发标记开始,并且无论何时发生并发标记开始,都会有一个暂停。

2018-07-16T14:30:58.489+0800: 2679.586: [GC concurrent-mark-start]
我知道并发标记阶段不会导致STW,但我不敢相信这只是巧合,因为我重复了很多次,它总是这样

以下是YourKit暂停期间的CPU使用率和内存使用率:

感谢@jspcal的建议,我得到了SafepointStatistics:

         vmop                    [threads: total initially_running wait_to_block]    [time: spin block sync cleanup vmop] page_trap_count
2566.430: G1IncCollectionPause             [     745          0              0    ]      [     0     0  2705     3   474    ]  0

G1IncCollectionPause花了将近3秒的时间到达安全点,而spin和block time都是0,而GC是VM暂停的一个来源,安全点(停止世界暂停)可以由其他操作启动,如刷新代码缓存、偏置锁定、某些调试操作等。下面是一个示例。要对这些安全点进行故障排除,请使用以下选项:

安全点:

-XX:+UnlockDiagnosticVMOptions
-XX:+PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount=1
-XX:+SafepointTimeout
-XX:SafepointTimeoutDelay=500
-XX:+LogVMOutput
-XX:LogFile=/var/log/jvm/vm.log
总承包商:


最后我发现这是由jdk关于大型引用数组并发标记的错误引起的:


我的解决方案是将大型引用数组更改为分开的二维数组

如果您的应用程序受到CPU的限制,那么您可能会耗尽日志线程。如果您真的认为应用程序处于深层GC中,那么应该开始绘制堆使用情况图。也许看看一些内存/JVM分析器@flakes我已经更新了cpu和内存使用我得到了日志,G1IncCollectionPause花了很长时间。当旋转和阻塞时间为0时,我如何知道是什么导致了这样的暂停?使用
SafepointTimeout
可以看到哪些线程未能及时到达safepoint。我添加了“-XX:+SafepointTimeout-XX:SafepointTimeoutDelay=2000”,但没有打印超时。尽管如此,旋转和块是0,同步是非常大的(7秒)。不仅G1IncCollectionPause花了那么长时间,任何类型的操作都可能导致这种情况。这是否意味着整个过程都被冻结了?
-XX:+UnlockDiagnosticVMOptions
-XX:+PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount=1
-XX:+SafepointTimeout
-XX:SafepointTimeoutDelay=500
-XX:+LogVMOutput
-XX:LogFile=/var/log/jvm/vm.log
-verbose:gc
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCApplicationConcurrentTime
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails 
-Xloggc:/var/log/jvm/garbage.log
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=100M