什么时候Java本地变量适合GC

什么时候Java本地变量适合GC

本文介绍了什么时候Java本地变量适合GC?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下程序:

import java.io.*;
import java.util.*;

public class GCTest {

    public static void main(String[] args) throws Exception {
        List cache = new ArrayList();
        while (true) {
            cache.add(new GCTest().run());
            System.out.println("done");
        }
    }

    private byte[] run() throws IOException {
        Test test = new Test();
        InputStream is = test.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buff = new byte[256];
        int len = 0;
        while (-1 != (len = is.read())) {
            baos.write(buff, 0, len);
        }
        return baos.toByteArray();
    }

    private class Test {
        private InputStream is;

        public InputStream getInputStream() throws FileNotFoundException {
            is = new FileInputStream("GCTest.class");
            return is;
        }

        protected void finalize() throws IOException {
            System.out.println("finalize");
            is.close();
            is = null;
        }
    }
}

您希望最终确定当run方法中的while循环仍在执行且局部变量test仍在范围内时,是否会被调用?

would you expect the finalize to ever be called when the while loop in the run method is still executing and the local variable test is still in scope?

更重要的是,这种行为是在任何地方定义的吗? Sun是否有任何声明它是实现定义的?

More importantly, is this behaviour defined anywhere? Is there anything by Sun that states that it is implementation-defined?

这与之前提出的问题的方式相反,人们主要是关注内存泄漏。在这里,我们让GC积极地GCing一个我们仍然感兴趣的变量。你可能会期望,因为测试仍在范围内,它不会是GC。

This is kind of the reverse of the way this question has been asked before on SO where people are mainly concerned with memory leaks. Here we have the GC aggressively GCing a variable we still have an interest in. You might expect that because test is still "in scope" that it would not be GC'd.

对于记录,似乎有时测试工作(即最终命中OOM),有时它会失败,具体取决于JVM的实现。

For the record, it appears that sometimes the test "works" (i.e. eventually hits an OOM) and sometimes it fails, depending on the JVM implementation.

不保护这个代码编写顺便说一句的方式,这只是一个工作中出现的问题。

Not defending the way this code is written BTW, it's just a question that came up at work.

推荐答案

虽然对象不会出现如果垃圾仍在范围内,则收集垃​​圾,如果变量实际上没有在代码中进一步使用(因此您看到的行为不同),JIT编译器可能会将其带出范围,即使您在读取源代码时也是如此仍然似乎是在范围内。

While the object won't be garbage collected if it is still in scope, the JIT compiler might take it out of scope if the variable isn't actually used any further in the code (hence the differing behavior you are seeing) even though when you read the source code the variable still seems to be "in scope."

我不明白为什么你关心如果一个对象是垃圾收集,如果你不再在代码中引用它,但如果你想确保对象留在内存中,最好的方法是直接在类的字段中引用它们,甚至在静态字段中更好地引用它们。如果静态字段引用该对象,则不会收集垃圾。

I don't understand why you care if an object is garbage collected if you don't reference it anymore in code, but if you want to ensure objects stay in memory, the best way is to reference them directly in a field of a class, or even better in a static field. If a static field references the object, it won't get garbage collected.

编辑:是您要查找的明确文档。

Here is the explicit documentation you are looking for.

这不能假设。
Java规范和JVM规范都不保证
这个。

This can not be assumed. Neither the Java spec nor the JVM spec guarantees this.

仅仅因为变量在范围内,
并不意味着它指向
的对象是可达的。通常情况是

范围内变量指向的对象是可达的,但是
你的情况是不可以的。
编译器可以在jit时间确定
哪些变量已经死亡,而
在oop-map中包含这些变量。
由于nt
指向的对象可以[sic - 应该不能]从任何实时变量达到
,因此可以收取

Just because a variable is in scope, doesn't mean the object it points to is reachable. Usually it is the case that an object pointed to by an in-scope variable is reachable, but yours is a case where it is not. The compiler can determine at jit time which variables are dead and does not include such variables in the oop-map. Since the object pointed to by "nt" can [sic - should be cannot] be reached from any live variable, it is eligible for collection.

这篇关于什么时候Java本地变量适合GC?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 16:16