Java中的内存效率

Aid*_*dom 4 java memory optimization jvm

关于内存使用和变量实例化哪个更好或没有区别:

这个

for(int i = 0; i < someValue; i++)
{
    Obj foo = new Obj();
    Use foo.....
}
Run Code Online (Sandbox Code Playgroud)

相反:

Obj foo;

for(int i = 0; i < someValue; i++)
{
    foo = new Obj();
    Use foo.....
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*ood 11

没有区别.内存使用方面的任何潜在差异都将由编译器优化.

如果您编译(使用javap -c)这两个示例并比较字节码,您会发现字节码是相同的.当然,这取决于JVM版本.但由于这个例子是如此微不足道,因此可以安全地假设它们的内存效率都不高于另一个.


例1:

码:

public class example1 {
    public static void main(String[] args) {
        for (int i=0; i<10; i++) {
            Object a = new Object();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

字节码:

public class example1 extends java.lang.Object{
public example1();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   bipush  10
   5:   if_icmpge       22
   8:   new     #2; //class java/lang/Object
   11:  dup
   12:  invokespecial   #1; //Method java/lang/Object."<init>":()V
   15:  astore_2
   16:  iinc    1, 1
   19:  goto    2
   22:  return
}
Run Code Online (Sandbox Code Playgroud)

例2:

码:

public class example2 {
    public static void main(String[] args) {
        Object a;
        for (int i=0; i<10; i++) {
            a = new Object();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

字节码:

public class example2 extends java.lang.Object{
public example2();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_2
   2:   iload_2
   3:   bipush  10
   5:   if_icmpge       22
   8:   new     #2; //class java/lang/Object
   11:  dup
   12:  invokespecial   #1; //Method java/lang/Object."<init>":()V
   15:  astore_1
   16:  iinc    2, 1
   19:  goto    2
   22:  return
}
Run Code Online (Sandbox Code Playgroud)

  • 现在,这是一个敏捷的想法 - 荣誉 (3认同)
  • Joshua Bloch([*Effective Java*]的作者(http://java.sun.com/docs/books/effective/))会反驳,如**项45:最小化局部变量的范围**.:) (3认同)

mpr*_*hat 6

使用现代JVM两者都可以正常工作,编译器优化也会使两者都相同.

忽略编译器优化和现代JVM,第一种方法更好.

  • 你错误地比较了两种情况.顺便说一下,第一种方法更具可读性(没有不必要的对象范围). (2认同)

Thi*_*Tao 5

第一个示例在对象范围方面最有意义,但两者都应该像另一个一样具有内存效率.


And*_*ren 5

您的示例之间没有区别,正如其他答案中所指出的那样.但是,问题是:如果你的例子很慢,你应该怎么做?

如果要在真正的性能关键部分中减少分配/垃圾收集所花费的时间,请考虑重复使用对象,而不是在每次迭代时分配新对象.

foo = new Obj();
for(int i = 0; i < someValue; i++)
{
    foo.init(i);
    Use foo.....
}
Run Code Online (Sandbox Code Playgroud)

java性能调优(一本旧书,但在现代jvm:s和.NET clr中也是如此)

......对象的创建成本很高.如果重用同一个对象是合理的,那么你应该这样做.您需要注意何时不要拨打新电话.一个相当明显的情况是,当您已经使用了一个对象并且可以在您要创建同一个类的另一个对象之前将其丢弃.您应该查看该对象并考虑是否可以重置字段然后重用该对象,而不是将其丢弃并创建另一个对象.这对于经常使用和丢弃的对象尤其重要