Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用于垃圾回收的对象数_Java_Object_Inheritance_Garbage - Fatal编程技术网

Java 用于垃圾回收的对象数

Java 用于垃圾回收的对象数,java,object,inheritance,garbage,Java,Object,Inheritance,Garbage,鉴于: 接口动物{void makeNoise();} 马类器具{ 长重=1200L; public void makeNoise(){System.out.println(“whinny”);} } 公共级冰岛马{ public void makeNoise(){System.out.println(“vinny”);} 公共静态void main(字符串[]args){ 冰岛语i1=新冰岛语(); 冰岛语i2=新冰岛语(); 冰岛语i3=新冰岛语(); i3=i1;i1=i2;i2=null

鉴于:

接口动物{void makeNoise();}
马类器具{
长重=1200L;
public void makeNoise(){System.out.println(“whinny”);}
}
公共级冰岛马{
public void makeNoise(){System.out.println(“vinny”);}
公共静态void main(字符串[]args){
冰岛语i1=新冰岛语();
冰岛语i2=新冰岛语();
冰岛语i3=新冰岛语();

i3=i1;i1=i2;i2=null;i3=i1;//重要的东西在这里

interface Animal { void makeNoise(); }
class Horse implements Animal {
    Long weight = 1200L;
    public void makeNoise() { System.out.println("whinny"); }
}
public class Icelandic extends Horse {
    public void makeNoise() { System.out.println("vinny"); }
    public static void main(String[] args) {
        Icelandic i1 = new Icelandic();
        Icelandic i2 = new Icelandic();
        Icelandic i3 = new Icelandic();
        i3 = i1; i1 = i2; i2 = null; i3 = i1;  //<-- line 14
     }
 }
因此,
i3
立即失去其引用,因此原始对象已准备好收集

i1
i3
参考
i2
因此i1s原始对象已准备好收集

然后,
i2
将丢失其引用,因此所有3个都为null并被垃圾收集


我个人同意3。这是一个非常发人深省的问题。

所以每个对象都有一个长对象,所以当每个冰岛对象都被标记为垃圾收集时,它指向的
Long
值也是如此。因此:

Icelandic i1 = new Icelandic();
Icelandic i2 = new Icelandic();
Icelandic i3 = new Icelandic();
i3 = i1; i1 = i2; i2 = null; i3 = i1;

原始i3对象丢失,原始i1值丢失。i1和i3都指向原始i2,使其保持活动状态(i2指向null,使其不活动)。这将留下2个对象标记为垃圾收集(原始i1和原始i3)以及它们指向的
Long
值,为您提供了4个标记为垃圾收集的项。

在第14行之后,只有原始i2对象处于活动状态,没有指向原始i1和i3的引用,因此它们符合垃圾收集器的条件,并且该对象有一个基类型,一个长字段,将其丢失到,因此2*2=4;

我会选择冰岛的2个对象(对象1和对象3)。
因为每个冰岛人都持有一个长对象,它给了我们4。

这个问题,特别是坚持4这个特定的“正确”答案,没有多大意义,因为它对JVM如何工作提出了一些假设,这些假设在最好的情况下是幼稚的,或者根本是错误的

它做错的第一件事是假设知道有多少对象被创建过

main
方法创建了三个
Icelandic
实例,其中继承的字段
weight
初始化为
1200L
值。该值
1200L
通过使用允许但不需要频繁缓存请求的方法自动装箱转换为
Long
实例因此,我们无法预测此处创建的
Long
实例的数量,可能是一个或三个,但如果缓存不适用于所有调用,无论出于何种原因,甚至可能是两个

然后,代码将处理包含这三个实例的局部变量,并假定“after”只包含其中一个实例第14行但是在该行之后没有关联的代码,该状态可能与之相关。该行之后发生的唯一事情是从
main
方法返回,因此在第14行之后,所有局部变量都超出范围

是否存在可与“第14行之后”关联的执行点但是仍然在方法
main
中,
Icelandic
的一个实例在范围内,这取决于类文件中是否包含行调试信息,以及编译器如何将字节码指令映射到这些行号

如果编译器插入的
return
字节码指令未与第15行关联,则在
main
方法中创建的所有实例可能会在第14行之后被垃圾收集,但请记住,
Long
实例可能仍会从全局缓存引用,因此不符合垃圾收集的条件n、 我们根本无法预测


JVM执行还有另一个方面:优化。JVM可以执行“转义分析”如果对象创建对程序语义没有任何影响,则删除对象创建。在您的程序中,从JVM的角度来看,所有对象都是未使用的。因此,另一种合法的执行场景是,此
main
方法从不创建任何对象,然后根本没有符合垃圾收集条件的对象。

我们是在谈论bef吗还是在第14行执行之后?在第14行主方法关闭+1之后。然而,扮演魔鬼代言人的角色,我认为正确的答案实际上应该是“3或4,取决于实现”。尽管JLS声明-128和127之间的原始值必须始终被保留,因此必须保留相同的对象,但它也声明理想情况下,装箱一个给定的原语值p,总是会产生一个相同的引用。"因此,给定的兼容JVM实现很容易使那些
Long
值成为同一个对象,在这种情况下,只有三个实际对象才有资格收集!@berry120不是2个还是4个?如果所有三个长对象都引用同一个对象,那么只有两个
Icelandic
对象将获得GCd,因为他们的
权重
都指向了活的
冰岛人仍在使用的
长的
参考。我同意这不是一个好问题,但鉴于OP给出了正确的答案,我相信这是与之一致的理由。@KevinDiTraglia哦,当然,我只是把它作为附录指出而已!
Icelandic i1 = new Icelandic();
Icelandic i2 = new Icelandic();
Icelandic i3 = new Icelandic();
i3 = i1; i1 = i2; i2 = null; i3 = i1;