程序段3: 1.Object aobj = new Object ( ) ; //设定由new Object()而产生所分配的内存块为A
2.Object bobj = new Object ( ) ; //设定由new Object()而产生所分配的内存块为B
3.Object cobj = new Object ( ) ; //设定由new Object()而产生所分配的内存块为C
4.aobj = bobj;
5.aobj = cobj;
6.cobj = null;
7.aobj = null; 问:这段代码中,第几行的内存空间符合垃圾收集器的收集标准? 答:第7行。
行1-3分别创建了Object类的三个对象:aobj,bobj,cobj 行4:此时对象aobj的句柄指向bobj,所以该行的执行不能使aobj符合垃圾收集器的收集标准。 //问题一:但我自己认为这时从行4开始内存块A已经没有机会可以再被引用了,所以我认为内存块A此时可以被回收,我自己觉得应该可以选择行4的。请问我这样理解对吗?谢谢。行5:此时对象aobj的句柄指向cobj,所以该行的执行不能使aobj符合垃圾收集器的收集标准。 行6:此时仍没有任何一个对象符合垃圾收集器的收集标准。 行7:对象cobj符合了垃圾收集器的收集标准,因为cobj的句柄指向单一的地址空间。在第6行的时候,cobj已经被赋值为null,但由cobj同时还指向了aobj(第5行),所以此时cobj并不符合垃圾收集器的收集标准。而在第7行,aobj所指向的地址空间也被赋予了空值null,这就说明了,由cobj所指向的地址空间已经被完全地赋予了空值。所以此时cobj最终符合了垃圾收集器的收集标准。 但对于aobj和bobj,仍然无法判断其是否符合收集标准。
问题二:行4中 aobj = bobj;这个语句可不可以是这样理解的:给对象aobj赋予了新值为bobj,既重新分配了aobj的内存空间为bobj所代表的内存空间。谢谢。
问题三:垃圾回收指的是回收对象的句柄,还是回收对象所代表的内存块呢??
2.Object bobj = new Object ( ) ; //设定由new Object()而产生所分配的内存块为B
3.Object cobj = new Object ( ) ; //设定由new Object()而产生所分配的内存块为C
4.aobj = bobj;
5.aobj = cobj;
6.cobj = null;
7.aobj = null; 问:这段代码中,第几行的内存空间符合垃圾收集器的收集标准? 答:第7行。
行1-3分别创建了Object类的三个对象:aobj,bobj,cobj 行4:此时对象aobj的句柄指向bobj,所以该行的执行不能使aobj符合垃圾收集器的收集标准。 //问题一:但我自己认为这时从行4开始内存块A已经没有机会可以再被引用了,所以我认为内存块A此时可以被回收,我自己觉得应该可以选择行4的。请问我这样理解对吗?谢谢。行5:此时对象aobj的句柄指向cobj,所以该行的执行不能使aobj符合垃圾收集器的收集标准。 行6:此时仍没有任何一个对象符合垃圾收集器的收集标准。 行7:对象cobj符合了垃圾收集器的收集标准,因为cobj的句柄指向单一的地址空间。在第6行的时候,cobj已经被赋值为null,但由cobj同时还指向了aobj(第5行),所以此时cobj并不符合垃圾收集器的收集标准。而在第7行,aobj所指向的地址空间也被赋予了空值null,这就说明了,由cobj所指向的地址空间已经被完全地赋予了空值。所以此时cobj最终符合了垃圾收集器的收集标准。 但对于aobj和bobj,仍然无法判断其是否符合收集标准。
问题二:行4中 aobj = bobj;这个语句可不可以是这样理解的:给对象aobj赋予了新值为bobj,既重新分配了aobj的内存空间为bobj所代表的内存空间。谢谢。
问题三:垃圾回收指的是回收对象的句柄,还是回收对象所代表的内存块呢??
解决方案 »
- read()返回的到底是啥?是读取的那个字符的
- 有关java组件的设置
- java可否传递数据集?
- 怎样解决tomcat中get提交中文参数为乱码的问题
- 读取班级成员的问题
- 关于List<T extends Object> list = new ArrayList<T extends Object>()
- 大侠赐教:CLASSPATH有什么作用
- 我正在学习java编数据库程序,用的是mssql7,都在一台机器上,我应该怎么用jdbc驱动?
- 我刚学java我想问一下,如果做下拉菜单,应该咋做?最好能给俺详细讲一下,俺是菜鸟!
- 有没有办法让独立的Frame/JFrame "keep on top"?
- 一个项目中,不启动项目,想调试其中一个类中的一个方法,我在这个类中添加了main来调用这个方法,请问如何能做到这样调式
- 具体的,,,,用哪一个方法可以统计出一个数组中数的个数
这行执行之后,第一行分配的对象满足垃圾回收的条件,因为引用aojb指向了bobj指向的对象,原来第一行创建的对象已经没有引用指向了。第七行执行完毕之后,第三行创建的对象满足垃圾回收条件垃圾回收指的是回收对象对应的内存块,在堆空间中。不要迷信答案。
垃圾收集器的收集标准只有两个
[标准1]句柄指向null
[标准2]句柄被赋予新的内存空间注意这时你已经是JVM
4.aobj = bobj; // 这时aobj这个引用的地址改变,而bobj并不指向null,所以[标准1]和[标准2]都不符合
// 楼主说“重新分配了aobj的内存空间”我个人认为不妥
// 这里只是aobj的值被覆盖了
// 就相当于 aobj = 0x00001; bobj = 0x00002;
// 那么 aobj = bobj;的结果就是 aobj和bobj都等于0x00002;
// 这个0x00002就是bobj一开始指向的对象的内存地址
5.aobj = cobj;
6.cobj = null; // cobj指向null,但aobj还在坚持
7.aobj = null; // aobj这时也指向null,那个对象被永久抛弃了
基本数据类型存在于栈中,它存入的其内容值
对象类型在栈中存入的是引用,也就是句柄
在堆中存入的才是数据
垃圾回收只清除堆中内容
所以垃圾回收指的是回收对象所代表的内存
当aobj = bobj;时就把第一行创建的对象失去引用了。
JVM没有你想象的那样聪明
这一行没有出现引用指向null
也没有出现引用指向新的对象
所以不符合垃圾收集器的收集标准
比如
Object o1=new Object();
这里o1指向一个内存块
Object o2=o1;
这里o2和o1指向了同一个内存块
o1=null;
这里之后,o2还是指向原来的内存块而不是null,所以,那个内存块还是有人要的(o2);
所以它不会引发垃圾回收
任何对象都有scope,出了作用域会自动回收
public static void main(String[] args) {
Test t1 = new Test();
Test t2 = new Test();
t1 = t2;
System.gc();
}
@Override
protected void finalize() throws Throwable {
System.out.println("i am a garbage");
super.finalize();
}
}
输出有一行:
i am garbage
确实会调用析构函数,但这并不等于说垃圾回收已经完成Java语言到目前为止并没提供
释放已分配内存的显示可调用方法System.gc();
这只是通知JVM可以回收,但结果不得而知回不回收要看引用类型的强弱程度
请问Java中析构函数何解???