Какой метод является наименее навязчивым для создания дампов потоков в java?

Мне известны следующие методы создания дампов потоков в java:

  • убить -3
  • jstack
  • JMX изнутри JVM
  • JMX-пульт
  • JPDA (удаленно)
  • JVMTI (C API)

Какой из этих методов наименее вреден для производительности JVM?


person Ovesh    schedule 07.11.2014    source источник


Ответы (2)


Если вам просто нужно вывести все трассировки стека на stdout, kill -3 и jstack должны быть самыми дешевыми. Функциональность изначально реализована в коде JVM. Никаких промежуточных структур не создается — ВМ печатает все сама, пока ходит по стекам.

Обе команды выполняют одну и ту же операцию с виртуальной машиной, за исключением того, что обработчик сигналов печатает трассировку стека локально в stdout процесса Java, а jstack получает выходные данные от целевой виртуальной машины через IPC (сокет домена Unix). в Linux или Именованный канал в Windows).

jstack использует внутренний механизм Динамического подключения. Вы также можете использовать Dynamic Attach напрямую, если хотите получать трассировку стека в виде простого потока байтов.

import com.sun.tools.attach.VirtualMachine;
import sun.tools.attach.HotSpotVirtualMachine;
import java.io.InputStream;

public class StackTrace {

    public static void main(String[] args) throws Exception {
        String pid = args[0];
        HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine.attach(pid);

        try (InputStream in = vm.remoteDataDump()) {
            byte[] buf = new byte[8000];
            for (int bytes; (bytes = in.read(buf)) > 0; ) {
                System.out.write(buf, 0, bytes);
            }
        } finally {
            vm.detach();
        }
    }
}

Обратите внимание, что все упомянутые методы в любом случае работают в безопасной точке виртуальной машины. Это означает, что все потоки Java останавливаются на время сбора трассировки стека.

person apangin    schedule 07.11.2014

Наиболее эффективным вариантом, вероятно, будет использование API ThreadMXBean.dumpAllThreads() вместо запроса дампа текстового потока, записанного на диск: http://docs.oracle.com/javase/7/docs/api/java/lang/management/ThreadMXBean.html#dumpAllThreads(boolean,%20boolean)

Конечно, можно ли это использовать, зависит от того, нужен ли вам файл дампа потока или просто данные.

person Chris Bailey    schedule 07.11.2014
comment
На самом деле это худший вариант. Представление трассировки стека ThreadInfo[] в среде Java требует большого объема кучи памяти и требует много времени для построения и печати. - person apangin; 07.11.2014