是否有可能在Java中强制垃圾收集,即使这很棘手?我知道System.gc();和Runtime.gc ();但他们只建议做GC。如何强制GC?


当前回答

我想在这里补充一些东西。请不要说Java运行在虚拟机而不是实际的机器上。虚拟机有自己的与机器通信的方式。它可能因系统而异。现在,当我们调用GC时,我们要求Java虚拟机调用垃圾收集器。

由于垃圾收集器是与虚拟机一起使用的,我们不能强迫它当场进行清理。相反,我们将请求与垃圾收集器一起排队。这取决于虚拟机,在特定时间之后(这可能因系统而异,通常在分配给JVM的阈值内存已满时),实际机器将释放空间。: D

其他回答

在OutOfMemoryError的文档中,它声明除非虚拟机在完整的垃圾回收后未能回收内存,否则它不会被抛出。因此,如果您一直分配内存直到出现错误,那么您将已经强制进行完整的垃圾收集。

想必您真正想问的问题是“如何回收我认为应该通过垃圾收集回收的内存?”

真的,我不懂你。而是成为 清楚“无限物体创造” 我是说有一些 代码在我的大系统做创建 可以处理的对象,并在其中生活 回忆,我无法得到这一片 其实是代码,只是个手势!!

这是正确的,唯一的姿态。你已经有了很多标准答案。让我们一个一个来看:

我无法得到这段代码 实际上

正确,没有真正的jvm——这只是一个规范,一堆描述期望行为的计算机科学…我最近研究了如何从本地代码初始化Java对象。要得到你想要的东西,唯一的方法就是执行所谓的主动置空。如果做错了,错误是非常糟糕的,我们必须将自己限制在问题的原始范围内:

我大系统里的一段代码 创建对象

这里的大多数海报会假设你说你正在处理一个界面,如果是这样的话,我们就必须看看你是一次被交付整个对象还是一个项目。

如果你不再需要一个对象,你可以将null赋值给该对象,但如果你弄错了,就会生成一个空指针异常。我敢打赌,如果您使用NIO,您可以实现更好的工作

任何时候你或我或其他人得到:“拜托,我非常需要那个。”这几乎是一个普遍的前兆,几乎完全破坏你正在努力工作....写一个小的示例代码,从它消毒任何实际使用的代码,并向我们展示您的问题。

不要沮丧。通常情况下,这意味着您的dba正在使用从某个地方购买的包,并且原始设计没有针对大规模数据结构进行调整。

这很常见。

如果您正在运行内存并得到一个OutOfMemoryException,您可以尝试通过java -Xms128m -Xmx512m开始编程来增加java可用的堆空间的数量,而不仅仅是java。这将使您的初始堆大小为128Mb,最大堆大小为512Mb,远远超过标准的32Mb/128Mb。

有一些间接的方法来强制垃圾收集器。您只需要用临时对象填充堆,直到垃圾收集器执行为止。我已经创建了一个类,它以这样的方式强制垃圾收集器:

class GarbageCollectorManager {

    private static boolean collectionWasForced;
    private static int refCounter = 0;

    public GarbageCollectorManager() {
        refCounter++;
    }

    @Override
    protected void finalize() {
        try {
            collectionWasForced = true;
            refCounter--;
            super.finalize();   
        } catch (Throwable ex) {
            Logger.getLogger(GarbageCollectorManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public int forceGarbageCollection() {
        final int TEMPORARY_ARRAY_SIZE_FOR_GC = 200_000;
        int iterationsUntilCollected = 0;
        collectionWasForced = false;

        if (refCounter < 2) 
            new GarbageCollectorManager();

        while (!collectionWasForced) {
            iterationsUntilCollected++;
            int[] arr = new int[TEMPORARY_ARRAY_SIZE_FOR_GC];
            arr = null;
        }

        return iterationsUntilCollected;
    }

}

用法:

GarbageCollectorManager manager = new GarbageCollectorManager();
int iterationsUntilGcExecuted = manager.forceGarbageCollection();

我不知道这个方法有多有用,因为它不断地填充堆,但如果你有任务关键的应用程序必须强制GC -当这可能是Java强制GC的可移植方式。

您可以尝试使用Runtime.getRuntime(). GC()或使用实用方法System.gc()注意:这些方法不能确保GC。它们的作用范围应该限制在JVM中,而不是在应用程序中以编程方式处理它。