2017-02-15 1 views
0

jvm은 루프 내부에서 데칼을 사용하거나 반복 할 때마다 새 참조를 만들 때 기존 참조를 다시 사용합니까? 예 :루프에서 참조 재사용

for (SomeObject o : collectionsOfObjects){ 
    Date temporaryDate = o.getDate(); 
} 

Date temporaryDate = null; 
    for (SomeObject o : collectionsOfObjects){ 
    temporaryDate = o.getDate(); 
    } 

그냥 모든 루프 우리가 Date 형의 새로운 기준을 만들거나 어쩌면 아래를 최적화 JVM 이후 첫 번째 예는 더 많은 메모리 소비가 발생합니다 궁금 있는지 확인하고 반복 할 때마다 동일한 참조를 사용합니다.

+0

어떻게 참조를 다시 사용할 수 있습니까? – Andremoniy

+0

시작과 다른 객체를 가리킬 수 있습니다 – marm

+3

"참조"라는 단어를 잘못 사용하고있는 것 같습니다. "변수'temporaryDate'는 각 반복마다 동일한 저장 위치를 ​​사용합니까? (참조는 변수의 * 값 *이며 반복되는 객체에 따라 달라집니다.) –

답변

0

로컬 변수의 범위는 컴파일 타임 아티팩트입니다. 컴파일러 (예 : javac)가 소스 코드에서 바이트 코드를 생성하면이 정보는 이미 손실됩니다.

Java 바이트 코드는 로컬 변수에 해당하는 위치 번호로 stack frame 내의 저장소를 참조합니다. 이러한 위치에 지역 변수를 할당하고 스택 프레임에 필요한 최대 저장 공간을 계산하는 작업은 컴파일시에 수행됩니다.

컴파일러는 분리 된 범위를 갖는 변수에 대해 스택 프레임 내에서 저장소를 재사용 할 수 있지만 일반적으로 필요하지는 않습니다. 그러나 귀하의 예에서는 분리 된 범위의 변수가 없습니다. 루프의 본문에는 동시에 세 변수가 있습니다 (temporaryDate, o). 이름이없는 변수는 Iterator입니다. 이 변수가 모두 동시에 존재하는 지점이 있기 때문에 서로 다른 저장 위치를 ​​가져야하며 스택 프레임은 적어도 3 개의 크기를 가져야합니다. 이는 두 변형 모두에 적용되므로 관련성이 없습니다.

그러나 스택 프레임 내의 저장소는 분리 된 범위의 변수에 대해서만 재사용 할 수 있으므로 변수의 범위를 제한하는 것이 좋습니다 (어쨌든 좋은 방법입니다). 작성시

for(SomeObject o : collectionsOfObjects){ 
    Date temporaryDate = o.getDate(); 
} 
for(OtherObject other : collectionsOfObjects){ 
    String n = other.getName(); 
} 

첫 번째 루프에 필요한 세 변수의 저장은 두 번째 루프에서 다시 사용할 수 있습니다 (다른 유형은 중요하지 않음). temporaryDate이 루프 외부에서 선언 된 경우 두 번째 루프에서 해당 저장소를 다시 사용하는 것은 불가능합니다.

스택 프레임은 메소드 항목에 할당되고 어쨌든 메소드 이탈시 삭제된다는 점에 유의하십시오. 지역 변수의 선언은 할당이나 어떤 액션을 일으키지 않습니다. 런타임에는 실제 읽기 및 쓰기 만 중요합니다. 따라서 변수를 선언하는 방식은 성능에 영향을 미치지 않습니다.

JVM이 코드 최적화 (HotSpot/OpenJDK와 같은 정교한 JVM)를 시작할 때 코드는 Static single assignment form으로 코드를 변환하여 선언과 완전히 다르게 보일 수 있습니다. 이 형식을 사용하면 사용하지 않는 변수를 완전히 제거하거나, 같은 값을 예측 가능하게 유지하면서 중복 계산을 제거하거나 예측 된 결과로 대체하는 등 근본적인 최적화가 가능합니다.

관련 문제