NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    Java 16. Java의 박싱과 언박싱. (Boxing, Unboxing and Heap, Stack)

    페이지 정보

    본문

    안녕하세요. 소심비형입니다. 오늘은 Java의 기본중에 기본인 boxing과 unboxing에 대해서 알아보겠습니다. 기본이긴 하지만 상당히 중요한 내용으로 이부분은 확실하게 이해하고 넘어가는게 좋겠습니다. 박싱과 언박싱은 Java와 C#이 거의 동일한 개념을 가지고 있습니다.

     

    박싱은 원시 타입(C#에서는 값 형식)을 객체(Object) 형식으로 변환하는 프로세스를 말합니다. JVM(Java Virtual Machine)은 원시 타입(Primitive type)을 박싱할 때 해당 타입에 대응되는 Class로 래핑(Wrapping)하고 관리되는 힙(Heap)에 저장합니다. unboxing은 개체에서 값 형식을 추출합니다. 아래는 Java의 원시 타입과 포장된 Wrapper class입니다.

     원시 타입 (Primitive type) 

     래퍼 클래스 (Wrapper class) 

     byte

     Byte

     short

     Short

     int

     Integer

     long

     Long

     float

     Float

     double

     Double

     char

     Character

     boolean

     Boolean

     

     

    C#과는 다르게 Java는 1.4버전 전까지 명시적으로 boxing과 unboxing을 구현해야 했습니다. 하지만, 1.5 이후부터 Wrapper클래스를 생성하지 않도록 하고 있습니다. Auto boxing은 자바 컴파일러가 원시 타입을 해당 개체에 래핑할 때 자동으로 변환이 이루어집니다. 반대로 래핑된 값을 원시 타입에 할당할 때 Auto unboxing이라고 부릅니다.

    Java 1.4

    Boxing

    Integer defaultAge = new Integer(20);

    Unboxing

    int yourAge = defaultAge.intValue();

     

     

    Java 1.5

    Auto boxing

    Integer defaultAge = 20;

    Auto unboxing

    Integer defaultAge = new Integer(20);int yourAge = defaultAge;

     

     

    Memory - Heap, Stack?

    응용 프로그램이 실행되는 동안 저장되는 데이타들은 형식에 따라 메모리에 저장되는 영역이 다릅니다. 아래 이미지는 메모리에 저장되는 영역을 나타내고 있습니다.

    Wd5lYbt.png

     

     

    스택(Stack): 메소드내에서 선언된 지역 변수로, 블록 내에서만 메모리 할당이 이루어집니다. 이곳에 할당된 값은 블록을 벗어나거나 제어가 종료되면 자동으로 메모리에서 해제됩니다. 이말은 컴파일시 변수들의 크기가 정해지며 그만큼 시스템은 필요한 메모리를 미리 할당할 수 있게 됩니다.

     

    힙(Heap): 동적으로 할당된 메모리로, 힙 영역에 주소값을 가지게 됩니다. 힙에 할당된 메모리는 사용자가 강제로 해제할수도 있지만, 보통은 가비지 컬렉터(Garbage Collector)가 메모리에서 해제합니다. 컴파일시에 변수의 크기가 정해지지 않으며, 실행중에 메모리가 할당되기 때문에 동적 메모리라고도 합니다.

     

    데이타(Static data): 전역 변수나 정적 변수들이 저장되며 이 영역도 스택과 마찬가지로, 시스템에 의해 할당 및 해제되며 컴파일시 크기가 정해지고 할당되는것도 같습니다. 하지만 스택과 다른점은 데이타의 수명인데, 스택 영역은 메소드 또는 블록내에서만 존재하는 반면 데이타 영역은 응용 프로그램이 실행될 때 메모리에 할당되어 이 응용 프로그램이 종료될 때 메모리에서 해제되게 됩니다.

     

    참고로, 메모리에 할당된 값 또는 데이타가 정상적으로 해제(삭제)되지 않으면, 쓰레기 데이타가 메모리에 쌓이게 됩니다. 이런 현상을 메모리 릭(Memory leak)이라고 부릅니다. 전산학에서는 보통 "메모리 누수"라고 표현하기도 합니다.

     

    아래 예제는 unboxing에 대해 잘 설명하고 있습니다.

    package ObjectOrientedProgramming;
     
    import java.util.ArrayList;
    import java.util.List;
     
    public class BoxingUnboxing {
        public static void main(String[] args) {  
      Integer i = new Integer(-8);  
     
      // 1. 메소드 호출을 통해 언박싱  
      int absVal = absoluteValue(i);  
      System.out.println("[" + i + "]의 절대값은 [" + absVal + "]입니다.");  
      List<Double> ld = new ArrayList<>();  
     
      // Π는 메소드 호출을 통해 오토 박싱  
      ld.add(3.1416);  
     
      // 2. 할당을 통해 언박싱  
      double pi = ld.get(0);  System.out.println("pi는 " + pi + "입니다."); 
     }
     
        public static int absoluteValue(int i) {
            return (i < 0) ? -i : i;
        }
    }
    

     

     

    위 코드를 실행한 결과는 아래와 같습니다.

    3Qo3snC.png

     

     

    이 내용이 중요한 이유는 성능과 밀접한 관계가 있기 때문입니다. 단순 할당에서는 boxing과 unboxing을 수행하는 데 많은 계산 과정이 필요합니다. 원시 타입을 boxing할 때는 새로운 개체를 할당하고 생성해야 합니다. 따라서 가급적이면 제네릭을 이용하는게 좋습니다. 이는 형식 지정자를 통해 자동으로 boxing이 발생되는 것을 방지할 수 있습니다.

     

    다음 시간에...

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.