Jai*_*zel 7 java garbage-collection
我可以从垃圾收集器中看到这种奇怪的行为
public class A {
public static void main(String[] args) {
String foo;
try {
foo = "bar";
int yoo = 5; //1
} catch (Exception e) {
}
int foobar = 3;//2
}
}
Run Code Online (Sandbox Code Playgroud)
如果我去调试并在// 1上放置一个断点,则foo不为null且其值为"bar"但在断点中// 2 foo为null,这在调试时很难理解.我的问题是,是否有任何规范说这是垃圾收集器的合法行为
由于这个小变化,它不会收集垃圾:
public class A {
public static void main(String[] args) {
String foo;
try {
foo = "bar";
} catch (Exception e) {
throw new RuntimeException(e);
}
int foobar = 3;
}
}
Run Code Online (Sandbox Code Playgroud)
为什么?
在这种情况下,您在设置后不使用foo变量,因此JVM完全忽略变量甚至是合法的,因为它从未使用过,并且不会改变程序的结果.
但是,这在调试模式下不太可能发生.
在你的情况下,只要foo在范围内或你持有对它的引用(包括try/catch块之后的部分),foo就不应该得到GC.
编辑
实际上我得到的行为与你在Netbeans 7.1.1中用Java 7.0_03描述的行为相同......
一个问题可能是因为您没有设置默认值foo,您不能在try/catch块之后使用它(它不会编译).
Bytcode
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String bar
2: astore_1
3: iconst_5
4: istore_2
5: goto 9
8: astore_2
9: iconst_3
10: istore_2
11: return
Run Code Online (Sandbox Code Playgroud)
String foo = null;作为第一个语句,在这种情况下,调试器会在try/catch块之后看到值:public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: ldc #2 // String bar
4: astore_1
5: iconst_5
6: istore_2
7: goto 11
10: astore_2
11: iconst_3
12: istore_2
13: return
Run Code Online (Sandbox Code Playgroud)
我不是代码专家,但他们看起来和我很相似......
结论
我个人的结论是,为了让调试器显示其值foo,它必须运行foo.toString()某种类型,这foo可能是catch块之后的有效语句,因为它可能尚未初始化.添加System.out.println(foo)该部分是不合法的(不编译).调试器有点丢失了值和显示的内容null.
为了说服自己这与GC无关,您可以尝试以下示例:
public static void main(String[] args){
String foo;
char[] c = null;
try {
foo = "bar";
c = foo.toCharArray();
int yoo = 5; //1
} catch (Exception e) {
}
int foobar = 3;//2
}
Run Code Online (Sandbox Code Playgroud)
在foobar行,你可以看到,c持有bar,但FOO显示为null.所以String仍然存在,但调试器无法显示它.
更有趣的例子:
public static void main(String[] args){
String foo;
List<String> list = new ArrayList<String>();
try {
foo = "bar";
list.add(foo);
int yoo = 5; //1
} catch (Exception e) {
}
int foobar = 3;//2
}
Run Code Online (Sandbox Code Playgroud)
在foobar行,foo显示为null,但list包含了"bar"...尼斯.
| 归档时间: |
|
| 查看次数: |
638 次 |
| 最近记录: |