java - 当老一代的jvm超过某个比例时如何自动转储内存?

标签 java garbage-collection jvm dump

我经常发现我繁忙的 Java Web 应用程序 full-gc。
我用jstat监控了这个过程并得到了以下结果:

Timestamp         S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                 
  2265116.2   0.00  58.20  79.23  62.57  62.29 273122 5729.765   727  281.867 6011.632 unknown GCCause      No GC               
  2265117.3   0.00  58.20  86.92  62.57  62.29 273122 5729.765   727  281.867 6011.632 unknown GCCause      No GC               
  2265118.3   0.00  58.20  97.72  62.57  62.29 273122 5729.765   727  281.867 6011.632 unknown GCCause      No GC               
  2265119.3  48.51   0.00  13.06  62.84  62.29 273123 5729.791   727  281.867 6011.658 unknown GCCause      No GC               
  2265120.2  48.51   0.00  51.12  62.84  62.29 273123 5729.791   727  281.867 6011.658 unknown GCCause      No GC               
  2265121.3   0.00  42.79  35.43  65.35  62.29 273124 5729.830   727  281.867 6011.697 unknown GCCause      No GC               
  2265122.2   0.00  39.46  50.81  80.86  62.29 273126 5729.998   728  281.883 6011.881 CMS Initial Mark     No GC               
  2265123.3   4.43   4.82  75.57  97.05  62.29 273129 5730.176   729  281.883 6012.060 unknown GCCause      Allocation Failure  
  2265124.3   4.43   4.82  75.57  97.05  62.29 273129 5730.176   729  281.883 6012.060 unknown GCCause      Allocation Failure  
  2265125.3   0.00   7.89  26.93  45.03  62.27 273130 5730.259   729  283.690 6013.949 unknown GCCause      No GC               
  2265126.3   0.00   7.89  35.96  45.03  62.27 273130 5730.259   729  283.690 6013.949 unknown GCCause      No GC               
  2265127.3   0.00   7.89  44.85  45.03  62.27 273130 5730.259   729  283.690 6013.949 unknown GCCause      No GC               
  2265128.3   0.00   7.89  52.71  45.03  62.27 273130 5730.259   729  283.690 6013.949 unknown GCCause      No GC               
  2265129.3   0.00   7.89  61.61  45.03  62.27 273130 5730.259   729  283.690 6013.949 unknown GCCause      No GC

我可以看到,每隔 20 分钟左右,内存中似乎就会创建一个非常巨大的对象。它太大了,无法放入年轻代,它直接分配在老一代中。
这通常会导致整个应用程序达到 FGC retio(70%)并触发 FGC,大对象立即被 GC ed。所以我无法通过堆转储确定它是什么。
这个问题使我的应用程序经常“震动”。
我的最大堆是 3g,年轻代是 521m。永久代始终稳定。
那么,有人可以告诉我如何知道这个巨大的物体到底是什么吗?
我可以配置 jvm 在 old-gen 超过某个指定比率时转储其内存吗?
或者任何其他有用的方法可以提供帮助?
非常感谢!

最佳答案

如果大对象由 FullGC 进行 GC,您可以使用类直方图来检查堆

使用-XX:+PrintClassHistogramBeforeFullGC-XX:+PrintClassHistogramAfterFullGC。 这至少会向您显示堆中分配的所有不同类型的对象,按占用空间和实例数量排序。

这是一种轻量级方法,但您至少可以检查您对“一个大对象”的假设。之后,您可以使用分析器进行深入研究,例如适用于 JDK7u40 及更高版本或 jProfiler 的任务控制,两者都运行良好。

关于java - 当老一代的jvm超过某个比例时如何自动转储内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23247947/

相关文章:

java - 垃圾收集器使用 2 个 WeakHashMaps

java - 为什么String类要这样设计呢?

java - JVM 不会终止

java - 我们应该使用 java 11 和 Ubuntu 18 的 Spring Boot 的 Java 垃圾收集器

java - Java 类链接解析步骤或初始化是否会导致加载其他解析的类?

java - 如何在android中显示内容(例如数学等类(class)),例如 "bac 2016"(digischool应用程序)

java - 用 Java 洗牌

java - 为第一轮 Switch Java 制作 If 语句

java - 集群环境下的hibernate一级缓存

.net - 有没有办法让.NET GC管理Cuda内存?