文章指出:
...当超出范围时,JVM 的有效实现不太可能将引用归零
我认为发生这种情况是因为这样的情况:
public void doSomething() {
for(int i = 0; i < 10 ; i++) {
String s = new String("boo");
System.out.println(s);
}
}
在这里,“高效 JVM”在 String 的每个声明中都使用了相同的引用,但如果 GC 没有启动,堆中将有 10 个新字符串。
在文章示例中,我认为对 foo 的引用保留在堆栈中,因为“高效 JVM”认为这很可能会创建另一个 foo 对象,如果是这样,它将使用相同的引用。想法???
public void run() {
try {
Object foo = new Object();
foo.doSomething();
} catch (Exception e) {
// whatever
}
while (true) { // do stuff } // loop forever
}
我还使用分析执行了下一个测试:
public class A {
public static void main(String[] args) {
A a = new A();
a.test4();
}
public void test1() {
for(int i = 0; i < 10 ; i++) {
B b = new B();
System.out.println(b.toString());
}
System.out.println("b is collected");
}
public void test2() {
try {
B b = new B();
System.out.println(b.toString());
} catch (Exception e) {
}
System.out.println("b is invisible");
}
public void test3() {
if (true) {
B b = new B();
System.out.println(b.toString());
}
System.out.println("b is invisible");
}
public void test4() {
int i = 0;
while (i < 10) {
B b = new B();
System.out.println(b.toString());
i++;
}
System.out.println("b is collected");
}
public A() {
}
class B {
public B() {
}
@Override
public String toString() {
return "I'm B.";
}
}
}
并得出结论:
teste1 -> b 被收集
teste2 -> b 是不可见的
teste3 -> b 是不可见的
teste4 -> b 被收集
...所以我认为,在循环中,JVM 在循环结束时不会创建不可见的变量,因为它们不太可能在循环外再次声明。
有什么想法吗??