我正在尝试在本地环境中模拟垃圾回收。有没有办法让JVM挂起5分钟?
我正在尝试在本地环境中模拟垃圾回收。有没有办法让JVM挂起5分钟?
pkill -STOP java; sleep $(( 5 * 60 )); pkill -CONT java
暂停所有Java进程5分钟。
pkill -TSTP java; sleep $(( 5 * 60 )); pkill -CONT java
略微减少了侵入性。
但这不会像垃圾收集器断开一样。
public static double slowpoke(int iterations) {
double d = 0;
for (int j = 1; j < iterations; j++) {
d += Math.log(Math.E * j);
}
return d;
}
public class SafepointTest {
public static double slowpoke(int iterations) {
double d = 0;
for (int j = 1; j < iterations; j++) {
d += Math.log(Math.E * j);
}
return d;
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread() {
@Override
public void run() {
double sideEffect = 0;
for (int i = 0; i < 10000; i++) {
sideEffect = slowpoke(999999999);
}
System.out.println("result = " + sideEffect);
}
};
thread.start();
new Thread(){
@Override
public void run() {
long timestamp = System.currentTimeMillis();
while (true){
System.out.println("Delay " + (System.currentTimeMillis() - timestamp));
timestamp = System.currentTimeMillis();
//trigger stop-the-world
System.gc();
}
}
}.start();
thread.join();
}
}
Delay 5
Delay 4
Delay 30782
Delay 21819
Delay 21966
Delay 22812
Delay 22264
Delay 21988
slowpoke(int iterations)
函数的参数值。-XX:+PrintGCApplicationStoppedTime
,这将在GC日志中实际报告所有安全点的暂停时间。不幸的是,此选项的输出缺少时间戳。-XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1
这两个选项将强制JVM在每个安全点后报告原因和时间。开发构建的热点JVM有一个名为UseLoopSafepoints
的选项。
使用此选项,您可以执行以下操作:
long
。这样可以防止虚拟机在循环退出之前达到安全点Thread.getAllStackTraces()
,这将触发一个安全点通过这些操作,所有的虚拟机线程都将被挂起,因为它们试图达到一个安全点,但是由于自旋循环的阻塞,安全点将被阻塞。 实际上,这应该类似于由于过多的GC工作而导致的长时间GC安全点。
注意:我还没有测试过这个。
JVM GC的设计是为了应用程序不会卡住,但据我理解,您希望所有线程都睡眠:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for(Thread thread : threadSet) {
if(thread == Thread.currentThread) //Make sure this one doesn't sleep.
continue;
thread.sleep({{Time in ms}});
}
Thread.sleep({{Time in ms}}); //Now we can make this thread sleep.
System.gc();
编辑:经过一些研究,我认为这是不可能的:
如何使另一个线程在Java中休眠
thread.sleep()
不起作用,因为你实际上没有调用一个实例方法,而是调用了一个静态方法(这应该会引发编译器警告)。thread.suspend()
可能会起作用。 - the8472
Thread.sleep()
命令暂停当前线程。 - Brett Walker