据我所知,Jconsole 或任何其他工具仅使用 System.gc()。没有其他选择。众所周知,java告诉大家不要依赖System.gc(),但这并不意味着它根本不起作用。
因此,在进行查询时,您似乎担心按下该按钮如何直接调用 GC 并且仍然 java 说 System.gc 仅“建议”调用 GC。我说,那个按钮也调用 System.gc() 并且它只是“建议”java 尝试 GC,并且它以某种方式发生,java 决定在那时自己执行 GC(它不能保证,但 java 以某种方式做到了。)
所以为了证明这个事实,我刚刚创建了一个简单的程序,它只创建了大量的对象。它用“System.gc()”注释了行。现在尝试先用注释的 System.gc() 运行相同的程序,然后取消注释 System.gc()。确保提供 VM 参数为 -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails。
package ravi.tutorial.java.gc;
/**
* Just to test GC. RUn with below VM arguments.
*
* -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails
*
*
* @author ravi.k
*
*/
public class TestGC {
public static A a;
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 100; i++) {
populateObjects();
System.out.println("population done for batch: " + i);
}
}
public static void populateObjects() {
for (int i = 0; i < 100000; i++) {
a = new A("A");
}
//System.gc();
}
}
class A {
String s;
public A(String s) {
this.s = s;
}
}
这里部分输出来自我的机器。
commened System.gc():这里gc是jre随意调用的。
population done for batch: 0
population done for batch: 1
population done for batch: 2
population done for batch: 3
population done for batch: 4
population done for batch: 5
population done for batch: 6
population done for batch: 7
population done for batch: 8
population done for batch: 9
0.332: [GC 0.332: [ParNew: 17024K->410K(19136K), 0.0024479 secs] 17024K->410K(83008K), 0.0025219 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
population done for batch: 10
population done for batch: 11
population done for batch: 12
population done for batch: 13
population done for batch: 14
population done for batch: 15
population done for batch: 16
population done for batch: 17
population done for batch: 18
population done for batch: 19
0.344: [GC 0.344: [ParNew: 17434K->592K(19136K), 0.0011238 secs] 17434K->592K(83008K), 0.0011645 secs] [Times: user=0.00 sys=0.01, real=0.00 secs]
population done for batch: 20
population done for batch: 21
population done for batch: 22
population done for batch: 23
population done for batch: 24
population done for batch: 25
population done for batch: 26
population done for batch: 27
population done for batch: 28
population done for batch: 29
population done for batch: 30
0.353: [GC 0.353: [ParNew: 17616K->543K(19136K), 0.0011398 secs] 17616K->543K(83008K), 0.0011770 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
population done for batch: 31
population done for batch: 32
population done for batch: 33
未注释的 System.gc():这里为每个批次调用 GC。现在 System.gc() 只是建议 GC,但 java 选择在那个时候自己运行 GC。这与其他工具中那个神奇的 GC 按钮的情况完全相同:)
0.337: [Full GC (System) 0.337: [CMS: 0K->400K(63872K), 0.0219250 secs] 3296K->400K(83008K), [CMS Perm : 4423K->4422K(21248K)], 0.0220152 secs] [Times: user=0.04 sys=0.00, real=0.02 secs]
population done for batch: 0
0.364: [Full GC (System) 0.364: [CMS: 400K->394K(63872K), 0.0161792 secs] 2492K->394K(83008K), [CMS Perm : 4425K->4425K(21248K)], 0.0162336 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]
population done for batch: 1
0.382: [Full GC (System) 0.382: [CMS: 394K->394K(63872K), 0.0160193 secs] 2096K->394K(83008K), [CMS Perm : 4425K->4425K(21248K)], 0.0160834 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
population done for batch: 2
0.399: [Full GC (System) 0.399: [CMS: 394K->394K(63872K), 0.0160866 secs] 2096K->394K(83008K), [CMS Perm : 4425K->4425K(21248K)], 0.0161489 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
population done for batch: 3
0.417: [Full GC (System) 0.417: [CMS: 394K->394K(63872K), 0.0156326 secs] 2096K->394K(83008K), [CMS Perm : 4425K->4425K(21248K)], 0.0156924 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
population done for batch: 4
0.434: [Full GC (System) 0.434: [CMS: 394K->394K(63872K), 0.0157274 secs] 2096K->394K(83008K), [CMS Perm : 4425K->4425K(21248K)], 0.0157897 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
population done for batch: 5
要添加更多,它就像线程。无法保证线程何时运行,但每当我们编写任何示例线程程序时,线程本身都会运行该时间。所以我们不应该责怪java它是如何在线程启动时运行的:)。Java 只是说不要依赖这些东西,但它们确实有效。此外,尽管它们在某些情况下工作并不意味着它们每次都会工作。即使是那些 jconsole 工具也可能无法执行 GC,只是我们从未见过。