Java优化:局部变量与实例变量

Java优化:局部变量与实例变量,java,garbage-collection,compiler-optimization,Java,Garbage Collection,Compiler Optimization,在Java中,如果我有很多本地对象,如果我将它们定义为实例变量,它会运行得更快吗?例如,如果我的func1()被多次调用,比如在一个循环中,JVM会在每次调用函数时继续实例化和垃圾收集列表2吗?相反,我应该重用相同的list1对象来防止垃圾收集和实例化开销吗 class A { List list1 = new ArrayList(); private void func1() { list1.clear(); // add new objects list1

在Java中,如果我有很多本地对象,如果我将它们定义为实例变量,它会运行得更快吗?例如,如果我的func1()被多次调用,比如在一个循环中,JVM会在每次调用函数时继续实例化和垃圾收集列表2吗?相反,我应该重用相同的list1对象来防止垃圾收集和实例化开销吗

class A {
   List list1 = new ArrayList();
   private void func1() {
      list1.clear();
      // add new objects list1

      List list2 = new ArrayList();
      // add new objects to list2
   }
}

优化器是否足够聪明,可以跳过垃圾收集并自动重用对象?

GC优化不是决定
Local
vs
Instance
变量的正确方法。如果一个变量需要由多个实例方法使用,那么使用实例变量是有意义的


你是对的,局部变量的使用可能会增加GC的活动性。

可能有各种用例,在决定是否使用本地变量或实例变量之前,你可能需要考虑这些用例。性能可能因用例而异


一个很好的例子是:-'避免创建不必要的对象。

还要考虑实例变量值的线程安全性。同一对象的两个线程需要同步访问实例变量数据,但在这里它将始终是一个新的局部变量数据对象。

如果-并且只有当-您已验证由于对象创建,您与GC有问题,您应该考虑将经验证的要创建的对象集中起来

为此,您不必重新发明任何轮子,您可以使用Javolutions utils实现它,在本例中使用调用:

List newOrReusedList=FastList.newInstance();
。。。以及相应的
FastList.recycle(FastList)
调用以使其可重用。(谢谢你,我忘了加这一点。)


(不过要注意,使用javolutions Fast*类可能会产生不同的性能:它们面向可预测的性能(实时系统)而不是速度,因此当它们的执行速度比java.lnag对应的慢时,可能会出现一些用例)

我用jdk1.6编写了一个小测试程序,如下所示

结果:
*594ms用于dostuff(它创建本地)
*dostuff2(使用实例)为58ms

公共类测试{
静态长计数器=0;
公共静态void main(字符串[]args){
long t1=System.nanoTime();
测试=新测试();

for(inti=0;i
Optimization.PREMATURE==Math.sqrt(EvilUtils.getAll(Evil.class))
评估结果为真…你确定这个问题会给你带来问题,还是只是一个过早优化的案例?我觉得这是第二个案例…只是好奇。想知道当我需要坐下来优化代码时,有哪些选项可用。但你也需要在不需要优化后手动释放所有未使用的快速列表m@JIV谢谢,我忘了加那个了。
List<Whatever> newOrReusedList = FastList.newInstance();
public class Test {

static long counter=0;
public static void main(String[] args) {
    long t1  = System.nanoTime();
    Test test = new Test();
    for (int i=0;i<1000000000;i++) {
        test.doStuff();//or dostuff2
    }
    long t2  = System.nanoTime();
    System.err.println((t2-t1)/1000000);
    System.err.println(counter); // to check it wasnt optimised away
}

private void doStuff() {
    List l = new ArrayList();
    if (l!=null) {
        counter++;
    }
}

List l2 = new ArrayList();
private void doStuff2() {
    if (l2!=null) {
        counter++;
    }
}
}