2010-07-24 2 views
1

에서 원시 래퍼 인스턴스화 원인 메모리 할당을 수행합니다는 PMD에서 JDK 1.6

IntegerInstantiation가 : 새로운 정수 (전화 JDK 1.5)에서 메모리 할당됩니다. Integer.valueOf()는보다 메모리에 친숙합니다.

ByteInstantiation : JDK 1.5에서 새로운 Byte()를 호출하면 메모리 할당이 발생합니다. Byte.valueOf()는보다 메모리에 친숙합니다.

ShortInstantiation : JDK 1.5에서 새로운 Short()를 호출하면 메모리 할당이 발생합니다. Short.valueOf()는 메모리에 친숙합니다.

LongInstantiation : JDK 1.5에서 새로운 Long()을 호출하면 메모리가 할당됩니다. Long.valueOf()는 메모리에 친숙합니다.

동일한 내용이 JDK 1.6에 적용됩니까? 컴파일러 또는 jvm이 각각의 valueof 메서드를 최적화하는 경우 그냥 궁금 해서요.

답변

3

은 이론적으로 컴파일러 new Integer(n) (예를 들어) 대신 권장 Integer.valueOf(n)의 사용 사례 작은 부분 집합을 최적화 할 수 있습니다.

우선 컴파일러가 == 또는 !=을 사용하는 다른 개체와 비교할 때 래퍼 개체를 절대 비교하지 못하도록 보장 할 수있는 경우에만 최적화를 적용 할 수 있습니다. (이 경우 최적화는 래퍼 객체의 의미를 변경하여 "=="및 "! ="은 JLS와 반대되는 방식으로 동작합니다.)

이러한 최적화가 구현할 가치는 없을 것입니다 :

  1. 최적화는 javadoc 등의 권장 사항을 무시하는 잘못 작성된 응용 프로그램에만 도움이됩니다. 잘 작성된 응용 프로그램의 경우, 최적화를 적용 할 수 있는지 테스트하면 최적화 프로그램의 속도가 느려집니다. 예 : JIT 컴파일러.

  2. 잘못 작성된 응용 프로그램의 경우에도 최적화가 허용되는 위치에 대한 제한은 new Integer(n)에 대한 실제 호출 중 최적화를위한 자격이 거의 없음을 의미합니다. 대부분의 경우 new 표현식으로 작성된 랩퍼가 사용될 수있는 모든 위치를 추적하는 것은 너 + 비쌉니다. 그림에 리플렉션을 포함 시키면 로컬 변수 이외에는 추적이 사실상 불가능합니다. 프리미티브 랩퍼의 대부분의 사용은이를 콜렉션에 넣는 것을 수반하므로, (실제 옵티 마이저에 의해) 최적화가 거의 불가능하다는 것을 쉽게 알 수 있습니다.

  3. 실제로 최적화가 적용된 경우에도 제한된 범위 내에서 n의 값만 도움이됩니다. 예를 들어, 큰 n에 대해 Integer.valueOf(n)을 호출하면 항상 새 개체가 만들어집니다.

1

Java SE 6에서도 마찬가지입니다. 일반적으로 새로운 객체 생성을 최적화하는 것은 어렵습니다. 예를 들어 new Integer(42) != new Integer(42)이 보장됩니다. 어떤 상황에서는 객체를 모두 가져올 필요가 없어지는 잠재 성이 있지만, 필자는 HotSpot 프로덕션 빌드에서 사용할 수없는 모든 것이 작성 시점에 빌드 된 것으로 생각합니다.

2

Java 6에서도 마찬가지입니다. Java 6에서 다음을 시도해보십시오.

System.out.println(new Integer(3) == new Integer(3)); 
System.out.println(Integer.valueOf(3) == Integer.valueOf(3)); 

System.out.println(new Long(3) == new Long(3)); 
System.out.println(Long.valueOf(3) == Long.valueOf(3)); 

System.out.println(new Byte((byte)3) == new Byte((byte)3)); 
System.out.println(Byte.valueOf((byte)3) == Byte.valueOf((byte)3)); 

그러나 큰 숫자를 사용하면 예상대로 최적화가 해제됩니다.

0

대개의 경우 중요하지 않습니다. 많은 시간 (예 : 10K 이상)으로 불리는 중요한 코드를 실행하고 있다고 확인하지 않으면 큰 차이를 내지 않을 것입니다.

의심스러운 경우 컴파일러에서 최적화가 수행되지 않는다고 가정합니다. 사실 거의 없습니다. 그러나 JVM은 많은 최적화 작업을 수행 할 수 있지만 객체를 만들지 않아도되는 것은 아닙니다. 일반적인 가정은 대부분의 경우 객체 할당이 충분히 빠릅니다.

참고 : 몇 번만 실행되는 코드 (기본값 : < 10K 시간)는 원시 코드로 완전히 컴파일되지 않으며 개체 할당보다 코드 속도가 느려질 수 있습니다.

0

탈출 분석 및 스칼라 교체가있는 최근 jvm에서 변수 범위가 하나의 메소드 또는 블록으로 제한되는 경우 보다 이 더 빠를 수도 있습니다. 자세한 내용은 Autoboxing versus manual boxing in Java을 참조하십시오.