gpt4 book ai didi

java - G1GC中如何触发Old Generation的回收

转载 作者:行者123 更新时间:2023-12-02 09:59:18 26 4
gpt4 key购买 nike

最近,我们的一些服务器由于段错误而崩溃。虽然我没有经过证实的根本原因,但我有预感,它与我们的应用程序的垃圾收集方式、我们所做的 GC 调整以及内存配置文件有关。

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

  • 崩溃之前,线程数量增加到高于正常水平
  • 在崩溃之前,总体堆使用情况的一般正常锯齿模式消失,并且堆大小在不减少的情况下增长
  • 在崩溃之前,堆的年轻一代始终处于较低水平,并且似乎不会调整大小或增加使用量
  • 在崩溃之前,老一代的大小会大于任何过去的老一代的大小,并且似乎不会被清理或收集
  • 段错误始终与 Activity 的 GC 线程有关,特别是 copy_to_survivor_space

虽然我没有看到内存不足发生的确凿证据,但我认为我们确实耗尽了应用程序的堆空间。如果 G1GC 在疏散或提升之前无法将年轻对象复制到幸存者空间,那么从逻辑上看,它似乎没有足够的空间来执行此操作。分析 GC 日志,我没有看到与 Humongous 对象有太多关系,因为我不认为它们占用了堆中的大量空间。

查看内存配置文件,我的直觉是我应该将 InitiatingHeapOccupancyPercent 减少到更接近默认值 45 的值,以便更早地触发收集周期。在我看来,特别是考虑到 Old Gen 的规模不断增长,需要更频繁地或至少更早地触发混合/完整 GC。 如何启动完整/混合收集?

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

<小时/>
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
#

memory snapshot

JVM 选项:

-XX:MaxHeapSize=30g
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:InitiatingHeapOccupancyPercent=70
-XX:-OmitStackTraceInFastThrow
-XX:+AlwaysPreTouch
-XX:+UseStringDeduplication
-XX:+UseCompressedOops

-Xloggc:/usr/local/company/logs/gc.log
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=100M
-XX:+PrintAdaptiveSizePolicy
-XX:+PrintGCApplicationConcurrentTime
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCCause
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-XX:+PrintReferenceGC
-XX:+PrintTenuringDistribution
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/usr/local/company/logs/heapdump_126960.hprof

最佳答案

Am I misinterpreting the segfault message and heading down the wrong path?

是的,堆 OOM 永远不应该导致段错误,相反,它们应该只触发 out of memory errors通过异常/可抛出机制。崩溃签名指向 JVM 错误或由外部因素(加载到 JVM 进程中的 native 库、内存损坏、Unsafe 的不正确使用)引起的堆损坏。

尝试升级您的 JVM,看看新版本中是否已修复该原因。如果这没有帮助,请尝试删除应用程序的部分内容、依赖项、java 代理等或在不同的硬件上运行。

关于java - G1GC中如何触发Old Generation的回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55751942/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com