Как я могу увидеть, какой java-сборщик мусора использует

Виртуальная машина Java поддерживает несколько стратегий сбора мусора.

Эта статья объясняет их.

Теперь мне интересно, какую (автоматически выбранную) стратегию использует мое приложение, есть ли способ, позволяющий JVM (версия 1.6) печатать эту информацию?

Изменить: JVM обнаруживает, находится ли он в режиме клиента или сервера. Итак, на самом деле вопрос в том, как я могу увидеть, что было обнаружено?

Ответ 1

http://java.sun.com/j2se/1.5.0/docs/guide/vm/gc-ergonomics.html, который применим для J2SE 6, также утверждает, что по умолчанию используется Parallel Collector.

Мы проверили это один раз на JVM 1.5, установив только

-server -Xms3g -Xmx3g -XX:PermSize=128m -XX:LargePageSizeInBytes=4m -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

и на выходе было показано

41359.597: [GC [PSYoungGen: 90499K->32K(377344K)] 268466K->181862K(2474496K), 0.0183138 secs]
41359.615: [Full GC [PSYoungGen: 32K->0K(377344K)] [PSOldGen: 181830K->129760K(2097152K)] 181862K->129760K(2474496K) [PSPermGen: 115335K->115335K(131072K)], 4.4590942 secs]

где PS означает параллельную очистку

Ответ 3

Поместите это в JAVA_OPTS:

-XX:+UseSerialGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

Для UseSerialGC мы увидим в журнале:

 7.732: [GC 7.732: [DefNew: 419456K->47174K(471872K), 0.1321800 secs] 419456K->47174K(1520448K), 0.1322500 secs] [Times: user=0.10 sys=0.03, real=0.14 secs]

В UseConcMarkSweepGC мы увидим в журнале:

 5.630: [GC 5.630: ['ParNew: 37915K->3941K(38336K), 0.0123210 secs] 78169K->45163K(1568640K), 0.0124030 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]

Для UseParallelGC мы увидим в журнале:

30.250: [GC [PSYoungGen: 441062K->65524K(458752K)] 441062K->76129K(1507328K), 0.1870880 secs] [Times: user=0.33 sys=0.03, real=0.19 secs]

Ответ 4

Как уже указывал Йоахим, статья, на которую вы ссылаетесь, описывает стратегии VM, предлагаемые Sun VM. Сама спецификация VM не предусматривает конкретных алгоритмов GC, и, следовательно, не имеет смысла иметь, например, перечислены значения для них в API.

Однако вы можете получить информацию из API управления:

List<GarbageCollectorMXBean> beans = 
    ManagementFactory.getGarbageCollectorMXBeans();

Итерируя эти beans, вы можете получить имя GC (хотя и только как строку) и имена пулов памяти, которыми управляют разные GC.

Ответ 5

Похоже, у нас есть более удобный способ определения версии GC во время выполнения. Всегда используйте инструменты, мое предложение. Для определения версии GC нам нужны два инструмента, которые поставляются с JVM (помещены в каталог jdk/bin):

  • VisualVM - запустите его и попробуйте профилировать какой-либо процесс (например, вы можете сами профиль VisualVM). Ваш профиль покажет вам PID процесса (см. Зеленые прямоугольники на снимке экрана).
  • jMap - запустите этот инструмент с параметрами -heap <PID> и найдите строку, предназначенную для типа Collector Garbage (см. розовую строку на снимке экрана).

введите описание изображения здесь

Ответ 6

Вы можете написать простую прогамму, которая подключается через jmx к вашему java-процессу:

public class PrintJMX {
  public static void main(String[] args) throws Exception {
    String rmiHostname = "localhost";
    String defaultUrl = "service:jmx:rmi:///jndi/rmi://" + rmiHostname + ":1099/jmxrmi";
    JMXServiceURL jmxServiceURL = new JMXServiceURL(defaultUrl);

    JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxServiceURL);
    MBeanServerConnection mbsc = jmxConnector.getMBeanServerConnection();


    ObjectName gcName = new ObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",*");

    for (ObjectName name : mbsc.queryNames(gcName, null)) {
      GarbageCollectorMXBean gc = ManagementFactory.newPlatformMXBeanProxy(mbsc,
        name.getCanonicalName(),
        GarbageCollectorMXBean.class);

      System.out.println(gc.getName());
    }

  }
}

Ответ 7

Лучший способ получить это: Перейдите в командную строку и введите следующую команду.

java -XX: + PrintCommandLineFlags -version

Он покажет вам результат:

C:\windows\system32>java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=132968640 -XX:MaxHeapSize=2127498240 -XX:+PrintCommandLineFl
ags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesInd
**ividualAllocation -XX:+UseParallelGC**
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)`enter code here`

Ответ 8

Как насчет информации, предоставляемой параметрами командной строки -verbose: gc и -XX: + PrintGCDetails? Разве это не полезно?

[Edit: Obviously not]