GC and assigning values in a for loop

南楼画角 提交于 2019-12-08 09:07:17

问题


I have a friend who told me the following but I couldn't give a good reason why.

someArray =......... 
int a;
for(int i=0; i < someArray; i++) {

a=someArray.get(i).length();
   // Do something
} 

He told me that he declared a outside of the for loop in order to avoid frequent garbage collection.

I thought declaring a inside of the for loop is more readable and thread safe.

However I couldn't disagree that different instances a no of iteration will be garbage collected if it's declared inside of for loop.

Any advise for me?


回答1:


Garbage collection handles objects. What you have is a primitive local variable a which will be allocated on the stack.

Therefore the whole premise of this question is wrong.




回答2:


Try decompiling both versions:

void outside(List<String> someArray) {
  // I've declared this outside the for loop too in order that the
  // the variables i and a are numbered the same in the two versions -
  // this makes no difference with respect to a.
  int i;
  int a;
  for(i=0; i < someArray.size(); i++) {
    a=someArray.get(i).length();
    // Do something
  }
}

void inside(List<String> someArray) {
  for(int i=0; i < someArray.size(); i++) {
    int a=someArray.get(i).length();
    // Do something
  }
}

The resulting bytecode is identical, so there is no performance or behavioural difference.

As such, you should use the one which is more readable, and has variables in tighter scope: declare the variable inside the loop.

  void outside(java.util.List<java.lang.String>);
    Code:
       0: iconst_0
       1: istore_2
       2: iload_2
       3: aload_1
       4: invokeinterface #2,  1            // InterfaceMethod java/util/List.size:()I
       9: if_icmpge     32
      12: aload_1
      13: iload_2
      14: invokeinterface #3,  2            // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      19: checkcast     #4                  // class java/lang/String
      22: invokevirtual #5                  // Method java/lang/String.length:()I
      25: istore_3
      26: iinc          2, 1
      29: goto          2
      32: return

  void inside(java.util.List<java.lang.String>);
    Code:
       0: iconst_0
       1: istore_2
       2: iload_2
       3: aload_1
       4: invokeinterface #2,  1            // InterfaceMethod java/util/List.size:()I
       9: if_icmpge     32
      12: aload_1
      13: iload_2
      14: invokeinterface #3,  2            // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      19: checkcast     #4                  // class java/lang/String
      22: invokevirtual #5                  // Method java/lang/String.length:()I
      25: istore_3
      26: iinc          2, 1
      29: goto          2
      32: return



回答3:


Since a is not an object which gets created with every loop iteration it will not be garbage collected at all.

Local, non object data types like int, float, bool,... are being kept on a stack. If the variable is out of scope they will be popped from the stack.

In case a would be an object the reference to the object would be removed with every iterration causing the object itself to become not referenced anymore which means it will be GCed at some point in the future.

More information: (Chapter 2.6) https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html



来源:https://stackoverflow.com/questions/37455332/gc-and-assigning-values-in-a-for-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!