Как автоматически выгружать память, когда old-gen из jvm превышает некоторое соотношение?

1

Я часто встречал свое занятое Java-приложение с полным 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 (что составляет 70%) и срабатывает FGC, поэтому большой объект GC-ed немедленно. Поэтому я не мог определить, что это за кучи кучи.
Эта проблема регулярно меняет приложение "землетрясения".
Моя максимальная куча составляет 3 г, а молодняк - 521 м. Перм-ген всегда стабилен.
Итак, может кто-нибудь сказать мне, как я могу узнать, что такое огромный объект?
Могу ли я настроить jvm для выгрузки своей памяти, когда old-gen превышает некоторое заданное соотношение?
Или могут помочь другие полезные методологии?
Огромное спасибо!

  • 0
    На какую строчку вы ссылаетесь? Единственный прыжок в старом поколении следует за небольшой коллекцией, это совершенно нормально. Я подозреваю, что нет огромного объекта.
  • 0
    Вы делаете небольшую коллекцию каждые пару секунд. Я предлагаю вам увеличить размер Eden, чтобы у вас не было столько молодых коллекций.
Показать ещё 5 комментариев
Теги:
garbage-collection
jvm
dump

2 ответа

0

Существует флаг JVM, который может вам пригодиться: -XX:+HeapDumpBeforeFullGC. Это заставит JVM сбрасывать всю кучу в файл перед крупным глобальным GC. Флаг управляемый. Это означает, что вы можете включать/отключать его во время выполнения через JMX с помощью JConsole, Misson Control или даже программно с помощью javax.management API:

MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean bean = ManagementFactory.newPlatformMXBeanProxy(
        server,
        "com.sun.management:type=HotSpotDiagnostic",
        HotSpotDiagnosticMXBean.class);
bean.setVMOption("HeapDumpBeforeFullGC", "true");
0

Если большой объект GC-ed от FullGC, вы можете использовать гистограмму класса для проверки кучи.

Используйте -XX:+PrintClassHistogramBeforeFullGC и -XX:+PrintClassHistogramAfterFullGC. Это, по крайней мере, покажет вам все классы классов, выделенные в куче, отсортированные по площади и количеству экземпляров.

Это легкий подход, но вы можете хотя бы проверить свою гипотезу о "одном большом объекте". После этого вы можете копаться в профилировщиках, например, Mission Control для JDK7u40 и выше или jProfiler, оба отлично работают.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню