Java 如何使用kill-3每30秒进行一次jave堆转储<;pid>;命令
请在这方面提供帮助,我想运行一个shell脚本,使用kill-3命令,它应该每30秒进行一次jave堆转储。提前谢谢。您尝试过这样一个简单的shell脚本吗Java 如何使用kill-3每30秒进行一次jave堆转储<;pid>;命令,java,shell,heap,dump,Java,Shell,Heap,Dump,请在这方面提供帮助,我想运行一个shell脚本,使用kill-3命令,它应该每30秒进行一次jave堆转储。提前谢谢。您尝试过这样一个简单的shell脚本吗 while true do jmap -dump:file=/tmp/java-`date +%s`.hprof PID_OF_JVM sleep 30 done 这将为每个快照创建一个文件。对于线程转储,可以使用类似的脚本: while true do jstack PID_OF_JVM > stack-`date +
while true
do
jmap -dump:file=/tmp/java-`date +%s`.hprof PID_OF_JVM
sleep 30
done
这将为每个快照创建一个文件。对于线程转储,可以使用类似的脚本:
while true
do
jstack PID_OF_JVM > stack-`date +%s`.txt
sleep 30
done
我想您可以使用
kill-3
而不是jstack
您可以使用这样的代码从java应用程序中转储线程
public static String getDumpFor(Thread thread) {
StringBuilder sb = new StringBuilder();
if (thread.isAlive()) {
StackTraceElement[] stackTrace = thread.getStackTrace();
sb.append(thread.toString()).append("\n")
.append(String.format(" State - %s,", thread.getState()))
.append(String.format(" Is daemon = %s,", thread.isDaemon()));
for (StackTraceElement s : stackTrace)
sb.append("\tat ").append(s.getClassName()).append(".").append(s.getMethodName()).append("(").append(s.getFileName()).append(":").append(s.getLineNumber()).append(")")
.append("\n");
}
return sb.toString();
}
public static void dumpActiveThreads() {
Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
Set<Thread> keySet = stackTraces.keySet();
System.out.println("\nThread dump begin:");
for (Thread thread : keySet)
dumpActiveThread(thread);
System.out.println("\nThread dump end.");
}
final ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(
new Runnable() {dumpActiveThreads()},
0,
30, TimeUnit.SECONDS);
公共静态字符串getDumpFor(线程){
StringBuilder sb=新的StringBuilder();
if(thread.isAlive()){
StackTraceElement[]stackTrace=thread.getStackTrace();
sb.append(thread.toString()).append(“\n”)
.append(String.format(“状态-%s,”,thread.getState()))
.append(String.format(“Is daemon=%s,”,thread.isDaemon());
用于(StackTraceElement s:stackTrace)
sb.append(“\tat”).append(s.getClassName()).append(“.”).append(s.getMethodName()).append(“(”).append(s.getFileName()).append(“:”).append(s.getLineNumber()).append(“))
.append(“\n”);
}
使某人返回字符串();
}
公共静态无效转储ActiveThreads(){
Map stackTraces=Thread.getAllStackTraces();
Set keySet=stackTraces.keySet();
System.out.println(“\n读取转储开始:”);
用于(螺纹:键集)
dumpActiveThread(线程);
System.out.println(“\n读取转储结束”);
}
然后像这样安排任务
public static String getDumpFor(Thread thread) {
StringBuilder sb = new StringBuilder();
if (thread.isAlive()) {
StackTraceElement[] stackTrace = thread.getStackTrace();
sb.append(thread.toString()).append("\n")
.append(String.format(" State - %s,", thread.getState()))
.append(String.format(" Is daemon = %s,", thread.isDaemon()));
for (StackTraceElement s : stackTrace)
sb.append("\tat ").append(s.getClassName()).append(".").append(s.getMethodName()).append("(").append(s.getFileName()).append(":").append(s.getLineNumber()).append(")")
.append("\n");
}
return sb.toString();
}
public static void dumpActiveThreads() {
Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
Set<Thread> keySet = stackTraces.keySet();
System.out.println("\nThread dump begin:");
for (Thread thread : keySet)
dumpActiveThread(thread);
System.out.println("\nThread dump end.");
}
final ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(
new Runnable() {dumpActiveThreads()},
0,
30, TimeUnit.SECONDS);
final ScheduledFuture ScheduledFuture=scheduledExecutorService.scheduledwithfixeddelay(
新的Runnable(){dumpActiveThreads()},
0,
30,时间单位(秒);
我没有使用kill-3
命令,但我使用了sunsdk提供的jmap
命令
您可以编写一个脚本,然后在脚本下面运行命令
${JAVA_HOME}/bin/jmap -dump:file=/home/MyDump.hprof PID
3将只提供线程转储,而不提供堆转储。线程转储意味着您只能检查JVM中每个线程的堆栈跟踪。但是您在linux上查找堆转储,然后需要使用以下命令。
jmap-dump:file=myheap.bin{pid,您希望获取其中的heap dump}。输出“myheap.bin”不是人类可读的,要读取文件,可以使用MAT工具。
MAT下载链接:你有没有研究过?@Thomas使用cron
每30秒触发一次?没错,cron只能每60秒触发一次。+1但是kill-3不会将堆栈转储到你运行它的控制台,不像jstack@BrianAgnew:谢谢,我首先尝试使用kill-3
,但我认为这是我的错,我看不到堆栈转储。kill-3会将其转储到进程的stdout(错误?),但jstack似乎会将其转储到jstack的控制台