如何在G1GC中触发旧一代的收集

时间:2019-04-18 18:33:23

标签: java garbage-collection g1gc

最近,由于段错误,我们的某些服务器已崩溃。尽管我没有得到证实的根本原因,但我确实有一种直觉,它与我们的应用程序如何进行垃圾回收,我们完成的GC调整以及内存配置文件有关。

调查这些崩溃的多次发生,我从JVM的角度确定了一种模式:

  • 崩溃之前,线程数增加到正常水平
  • 在崩溃之前,总体堆使用情况的通常正常的锯齿模式消失了,堆大小不断增加而没有减少
  • 在崩溃之前,堆的年轻一代一直很低,并且似乎不会调整大小或增加使用量
  • 在崩溃之前,旧一代的大小会大于以前的任何旧一代,并且似乎没有被清理或收集
  • segfault总是与活动的GC线程有关,特别是# dataframe is named f company month year_ly bookings_ly year_ty bookings_ty 0 a 1 2018 432 2019 253.0 1 a 2 2018 265 2019 635.0 2 a 3 2018 345 2019 525.0 3 a 4 2018 233 2019 NaN 4 a 5 2018 7664 2019 NaN 5 a 12 2018 224 2019 321.0 6 b 1 2018 543 2019 576.0 7 b 2 2018 23 2019 43.0 8 b 3 2018 64 2019 156.0 9 b 4 2018 143 2019 NaN 10 b 5 2018 41 2019 NaN 11 b 6 2018 90 2019 NaN f.reset_index(inplace=True) def aggFunct(row, df, last=3): series = df.loc[(df['index'] < row['index']) & (df['index'] >= row['index'] - last), 'bookings_ty'].fillna(0) ssum = series.sum() return ssum f.loc[f['bookings_ty'].isna(),'bookings_ty'] = f[f['bookings_ty'].isna()].apply(aggFunct, df=f, axis=1) f.drop('index',axis=1,inplace=True) f company month year_ly bookings_ly year_ty bookings_ty 0 a 1 2018 432 2019 253.0 1 a 2 2018 265 2019 635.0 2 a 3 2018 345 2019 525.0 3 a 4 2018 233 2019 1413.0 4 a 5 2018 7664 2019 1160.0 5 a 12 2018 224 2019 321.0 6 b 1 2018 543 2019 576.0 7 b 2 2018 23 2019 43.0 8 b 3 2018 64 2019 156.0 9 b 4 2018 143 2019 775.0 10 b 5 2018 41 2019 199.0 11 b 6 2018 90 2019 156.0

虽然我没有看到发生内存不足的确凿证据,但我认为我们确实为应用程序用尽了堆空间。如果G1GC无法在撤离或提升前将年轻物体复制到幸存者空间,那么从逻辑上讲,它没有足够的空间来这样做。在分析GC日志时,我认为Humongous对象没有太多关系,因为我认为它们并没有占用堆空间。

查看内存配置文件,我的直觉是我应该将copy_to_survivor_space减小到接近默认值45的水平,以便更早触发收集周期。在我看来,尤其是考虑到老一代的规模不断扩大,混合/完整GC的触发需要更频繁或更短的触发时间。 如何启动完整/混合收藏?

根据所提供的信息,关于我如何尽快触发收款还有其他想法或意见吗?我是否误解了段错误消息并走错了路?我还能做些什么来收集可能使我能够解决崩溃根本原因的信息?


InitiatingHeapOccupancyPercent

memory snapshot

JVM选项:

Detail
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f38aa2655f5, pid=6293, tid=0x00007f3894efe700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_162-b12) (build 1.8.0_162-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.162-b12 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x5c85f5]  G1ParScanThreadState::copy_to_survivor_space(InCSetState, oopDesc*, markOopDesc*)+0x45
#

1 个答案:

答案 0 :(得分:1)

  

我误解了段错误消息并走错了路吗?

是的,堆OOM绝不应导致段错误,而应仅通过异常/可抛出机制触发out of memory errors。崩溃签名指向JVM错误或由外部因素(JVM进程中加载​​的本地库,内存损坏,对Unsafe的错误使用)引起的堆损坏。

尝试升级JVM,并查看原因是否已在较新版本中解决。如果这样做没有帮助,请尝试删除部分应用程序,依赖项,Java代理等或在其他硬件上运行。