有没有一种方法可以在Java中启动积极而完整的垃圾回收?

16 浏览
0 Comments

有没有一种方法可以在Java中启动积极而完整的垃圾回收?

为了内存优化的原因,在分析过程中,我会启动垃圾回收器来检查对象在处理之后是否正确清理干净。但是,单次调用垃圾回收器是不足够的,而且好像也没有什么保证它会清理什么。有没有一种方法可以调用它,以确保在分析条件下它会尽可能地回收内存(当然在生产中这是没有意义的)?或者“多次调用”是“几乎确定”的唯一方法?还是我对垃圾回收器有了误解?

admin 更改状态以发布 2023年5月22日
0
0 Comments

强制分配可用的最大内存。当JVM处于OutOfMemoryError边缘时,它被迫运行GC。

byte[] boom = new byte[512 * 1024 * 1024]; // Assuming 512MB

显然是为了纯粹进行测试。

另一个选项是使用更好的分析工具。它将提供关于内存使用和GC可回收对象的更好报告。

0
0 Comments

总的来说,“完整垃圾收集”没有一个明确定义。GC检测无法访问的对象并回收它们。大多数GC的实现基于“循环”基础,一旦完整循环运行,就可以定义一个声音的“回收空间”的概念。因此,如果您可以运行完整的循环,并且该循环根本没有找到可回收的空间,并且应用程序处于“空闲”状态(例如不更新指针),则可以说您暂时达到了“完全收集”的状态。\n\n因此,您可能想要做以下操作:\n\n

Runtime r = Runtime.getRuntime();
r.gc();
long f = r.freeMemory();
long m = r.maxMemory();
long t = r.totalMemory();
for (;;) {
    r.gc();
    long f2 = r.freeMemory();
    long m2 = r.maxMemory();
    long t2 = r.totalMemory();
    if (f == f2 && m == m2 && t == t2) 
        break;
    f = f2; 
    m = m2; 
    t = t2; 
}   
System.out.println("Full GC achieved.");

\n\n此代码依赖于一些假设,其中最重要的是“Runtime.gc()”不仅仅是一个“提示”,而且确实强制进行一些GC活动。 Sun的JVM可以用“-XX:-DisableExplicitGC”标志启动,该标志将Runtime.gc()转换为无操作,实际上可以防止上面的代码执行任何操作。\n\n也有一些要注意的地方:\n\n- JVM可能有一些后台持续的活动,例如Timer线程。其中一些活动可能是“隐藏”的,即不是应用程序开发人员编写的代码。还要考虑AWT / Swing事件调度程序线程。\n- GC运行可能会触发额外的异步活动,通过可终结对象或软/弱/虚引用。这种活动必然是异步的,并且可能运行时间无限长。Runtime.gc()不会等待它完成。实际上这是一个定义问题:如果尚未处理终结器和引用队列,您是否认为GC是“完整”的?\n\n- 没有什么真正的东西强制上述代码终止…\n如果要进行“更完整”的GC,可以使用JVMTI接口(调试器使用的接口),该接口允许您运行GC,还可以暂停目标JVM线程,这使定义和实现“完整GC”状态要容易得多。

0