Antilog의 개발로 쓰다
article thumbnail
반응형

2020/11/23 - [개발로 쓰는 공부/Java 지식] - [Java] Wrapper class - Auto Boxing, Unboxing

 

[Java] Wrapper class - Auto Boxing, Unboxing

🙄 Auto Boxing 과 Auto Unboxing auto boxing과 unboxing은 사실 java를 배울때 서적에도 적혀있는 내용이지만, 개념을 배운후에 개발하다 보면 사실 망각하기 쉬운 부분이기도 한 부분인데요 Wrapper Classes와..

antilog.tistory.com

해당 글에서 Auto Boxing과 Auto Unboxing을 설명하며 아래와 같은 부분이 있었습니다.

Integer integerNumber = new Integer(1); 
Integer otherIntegerNumber = new Integer(1); 

// integerNumber와 otherIntegerNumber는 1이라는 Binary 값을 가지지 않습니다. 
// 1이라는 값이 담긴 Integer class의 주소를 담고 있기에 이 2가지 값의 주소가 다르므로 False 라는 결과가 나옵니다. 
System.out.println(integerNumber == otherIntegerNumber); 

// 결과 false

그러나 여기서 아주 재미있는 점이 있습니다.

// Test 1 Code
Integer integerNumber = 1;
Integer otherIntegerNumber = 1;
System.out.println(integerNumber == otherIntegerNumber);

위와 같은 코드에서 출력값은 어떤 값이 나올까요? true 일까요? false 일까요?

 

저번 포스팅에 따르면

Integer integerNumber = 1; 이것은 Integer integerNumber = Integer.valueOf(1);

결국은 new Integer(1) 을 반환할 것이라 예상되겠죠?

그렇다면 Test 1 code는 결국 이전에 설명한 코드와 같은 코드이므로 false 라는 값이 나올까요...?

 

정답은 놀랍게도 true 가 나옵니다.

그럼 이전에 설명한 코드가 오류일까요? 아래 상황으로 넘어가 봅시다.

// Test 2 code 
Integer integerNumber = 128;
Integer otherIntegerNumber = 128;
System.out.println(integerNumber == otherIntegerNumber);

이 경우에는 false라는 값이 나오게 됩니다. 왜 이런 일이 발생하게 될까요?


 

❓ IntegerCache class

이유를 알기 위해서 Integer Class안에 valueOf 메소드를 살펴보면 다음과 같은 코드를 발견할 수 있습니다.

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

위 코드를 잘 살펴보면, 받아온 i 라는 값이 캐싱된 최소값과 최대값 사이에 있다면 미리 캐시된 값을 던져주고 그렇지 않으면 새로운 Integer 인스턴스를 생성해 반환하고있다는 것을 알게됩니다.

 

직접 찾아보시면 위에 이유도 적혀있는데 간단히 말하자면.

-128~127의 값을 항상 캐싱하는데 이 사이의 값이 아주 빈번하게 사용되는 값이기 때문입니다.

 

캐싱을 하지 않는다면?
-128~127의 값을 항상 만들때마다 다른 곳에 만들어서 던져주어 Test 2 code에서 처럼 같은 128이라는 값이지만 다른 곳에 저장하게 됩니다.

즉 코드 안에서 여러번 -128~127 사이의 값으로 초기화가 이루어진다면 동일한 값이지만 메모리는 초기화 한 횟수만큼 늘어나게 되는것입니다.

 

자바는 이를 방지하고자 자주쓰이는 수를 미리 캐시하고 -128~127 사이의 값을 생성하여 초기화하는 경우 새로운 Integer 를 생성하지 않고 기존에 캐시해둔 값을 던져주어 메모리를 아낀다고 볼 수 있습니다.

이러한 캐시는 static block으로 IntegerCache class 가 메모리에 로드되는 처음에 초기화 됩니다.

 

또한 해당 클래스 상단 주석을 잘 읽어보면

/*
 * The cache is initialized on first usage.  The size of the cache
 * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
 * During VM initialization, java.lang.Integer.IntegerCache.high property
 * may be set and saved in the private system properties in the
 * sun.misc.VM class.
 */

위와 같은 부분이 있는데

-XX:AutoBoxCacheMax=<size>

해당 옵션을 JVM 옵션에 적어 캐시의 범위를 바꿀 수도 있습니다.

 

캐싱은 Integer뿐만 아니라 Byte, Short, Long, Charactor 에도 존재 합니다.

범위 수정은 Integer에서만 가능한것으로 보이고, 범위도 각각 조금씩 차이가 있습니다.

반응형
profile

Antilog의 개발로 쓰다

@Parker_J_S

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...