Java中的内存高效对象创建

时间:2011-12-08 12:16:37

标签: java object memory-management

我对java.Suppose中的对象创建有一个基本的疑问,我有两个类如下

Class B{  
    public int value=100;  
}

Class A{  
    public B getB(){  
        return new B();  
    }  
    public void accessValue(){
        //accessing the value without storing object B
        System.out.println("value is :"+getB().value);

        //accessing the value by storing object B in variable b       
        B b=getB();
        System.out.println("value is :"+b.value);

   }  
}

我的问题是,存储对象和访问值是否会使内存方面有任何差异或两者相同?

7 个答案:

答案 0 :(得分:3)

它们都是等价的,因为你两次都在实例化B。第一种方式只是第二种方式的缩短版本。

答案 1 :(得分:2)

以下代码片段使用的是匿名对象。这在以后的代码中无法重用。

//accessing the value without storing object B     
System.out.println("value is :"+getB().value); 

下面的代码通过将对象分配给引用来使用该对象。

//accessing the value by storing object B in variable b             
B b=getB();      
System.out.println("value is :"+b.value); 

内存和性能方面明显不同,只是在以后的版本中,堆栈帧有一个额外的指针。

答案 2 :(得分:1)

它是一样的。这样:B b = getB();只是让你的代码更具可读性。请记住,无论如何,该对象必须存储在内存中。

答案 3 :(得分:1)

如果你从不在这部分之后重复使用B-object,那么带有匿名对象的第一个选项可能更整洁:

  • 第二个选项需要一个额外的存储/加载命令(如Hot Licks所述),如果它没有被编译器优化
  • 可能首先将对象存储在变量中会为垃圾收集器创建轻微的开销而不是匿名对象,但这更像是“调查那个”而不是对我的明确陈述
  • 如果您确实想再次访问B,则将其中一个存储在自己的变量中会更快。

    编辑:嗯,我在打字时已经提到过这两点。

    答案 4 :(得分:0)

    在这种情况下,差异(如果有的话)不值得一提。在第二种情况下,如果编译器没有优化它们,可能会生成额外的字节码或两个字节码,但任何体面的JIT几乎肯定会将这两种情况优化为相同的机器代码。

    而且,无论如何,额外存储/负载的成本对于99.9%的应用程序来说是无关紧要的(在这种情况下由new操作淹没)。

    详细信息:如果查看字节码,在第一种情况下调用getB方法并在堆栈顶部返回一个值。然后getfield引用value并将其放在堆栈顶部。然后完成StringBuilder append以开始构建println参数列表。

    在第二种情况下,在astore调用之后会有一个额外的aloadgetB(指针存储/加载),并且StringBuilder的设置被卡在两者之间,所以副作用以源中指定的顺序发生。如果没有副作用担心编译器可能选择执行效率稍高的dupeastore序列。在任何情况下,一个体面的JIT都会认识到b从未再次使用并优化了商店。

    答案 5 :(得分:0)

    实际上,你只是给b的新对象引用的第二个实例没有区别。

    所以代码方面如果使用版本1则无法实现println,因为在第二种情况下你没有任何引用,除非你不断为每个方法调用创建新对象。

    答案 6 :(得分:0)

    如果不查看生成的机器代码,您将无法说出差异。 可以是JIT将局部变量“b”放到堆栈上。然而,更有可能J​​IT将优化b。取决于您正在使用的JRE和JIT。在任何情况下,差异都很小,只有在特殊情况下才有意义。