BACKEND

참조 타입과 메모리 관리 이해하기

주니어발록 2025. 5. 19. 16:03

Java를 처음 공부하는 개발자라면 데이터 타입에 대한 이해가 꼭 필요합니다. 데이터 타입에는 기본 타입(Primitive Type)참조 타입(Reference Type) 이 있는데, 이번 포스팅에서는 특히 참조 타입을 쉽고 자세하게 알아보겠습니다.


참조 타입이란 무엇인가요?

참조 타입(Reference Type)은 실제 데이터를 직접 저장하는 것이 아니라 데이터가 위치한 메모리의 주소(번지)를 저장하는 타입입니다. 쉽게 말해, 데이터가 저장된 곳의 위치를 알려주는 '주소'만 가지고 있다고 생각하면 됩니다.

Java의 참조 타입으로는 크게 다음과 같은 것들이 있습니다.

  • 클래스(Class)
  • 배열(Array)
  • 열거(Enum)
  • 인터페이스(Interface)

기본 타입과 참조 타입의 차이

기본 타입과 참조 타입의 가장 큰 차이점은 메모리에 저장되는 방식입니다.

  • 기본 타입(Primitive Type): 실제 값이 직접 변수에 저장됩니다.
  • 참조 타입(Reference Type): 값 자체가 아니라 값이 저장된 곳의 위치(주소)가 저장됩니다.

예를 들어 다음을 보겠습니다.

int number = 100; // 기본 타입
String name = "Java"; // 참조 타입

여기서 number는 숫자 100이라는 값이 직접 저장됩니다. 반면, name은 "Java"라는 문자열이 저장된 위치의 주소만 저장됩니다.

참조 타입의 메모리 구조 이해하기

Java 프로그램이 실행되면 JVM(Java Virtual Machine)은 메모리를 다음과 같이 구분하여 사용합니다.

  • 스택(Stack): 메소드가 호출될 때마다 메소드의 지역 변수들이 저장됩니다.
  • 힙(Heap): 객체가 생성될 때 객체가 저장되는 영역입니다.
  • 메소드 영역(Method Area): 클래스와 메소드의 정보가 저장되는 공간입니다.

예를 들어, 다음과 같은 코드가 있다고 가정합시다.

String greeting = new String("Hello, World!");

여기서 greeting이라는 참조 변수는 스택 영역에 위치하고, 객체 "Hello, World!"는 힙 영역에 위치합니다. 변수 greeting은 힙 영역에 있는 객체를 가리키는 주소만을 갖고 있습니다.

참조 타입의 비교 연산 (주소 비교)

참조 타입을 비교할 때 == 연산자는 객체의 내용을 비교하는 것이 아니라, 두 참조 변수가 같은 객체를 가리키고 있는지 (같은 주소를 가지고 있는지) 비교합니다.

String str1 = "Java";
String str2 = "Java";
String str3 = new String("Java");

System.out.println(str1 == str2); // true (같은 주소)
System.out.println(str1 == str3); // false (다른 주소)
System.out.println(str1.equals(str3)); // true (내용 비교)
  • str1 == str2는 참입니다. Java가 같은 문자열 리터럴은 재사용하기 때문입니다.
  • str1 == str3는 거짓입니다. str3은 명시적으로 새로운 객체로 생성했기 때문입니다.

객체의 내용 비교는 항상 .equals() 메소드를 사용해야 합니다.

NullPointerException이란?

참조 타입을 사용하다 보면 가장 흔하게 접하는 예외가 바로 NullPointerException입니다. 이는 참조 변수가 null인 상태에서 객체의 필드나 메소드를 사용하려 할 때 발생합니다.

String nullString = null;
System.out.println(nullString.length()); // NullPointerException 발생

이 오류를 방지하기 위해서는 항상 변수가 null인지 체크하고 사용해야 합니다.

if (nullString != null) {
    System.out.println(nullString.length());
}

 

배열과 다차원 배열 이해하기

배열은 여러 데이터를 하나의 변수로 묶어 관리할 수 있도록 해줍니다.

  • 1차원 배열
int[] numbers = {1, 2, 3, 4, 5};
  • 다차원 배열 (2차원 배열 예시)
int[][] matrix = { {1, 2}, {3, 4} };

배열을 new 연산자로 생성하면, 각 항목은 초기값으로 설정됩니다.

int[] arr = new int[5]; // 모든 항목이 0으로 초기화

배열 복사는 System.arraycopy() 메소드를 사용하여 수행할 수 있습니다.

int[] source = {1, 2, 3};
int[] target = new int[3];
System.arraycopy(source, 0, target, 0, source.length);

 

main() 메소드의 매개변수 String[] args의 역할

Java 프로그램의 진입점은 항상 main() 메소드입니다. 이 메소드의 String[] args 매개변수는 프로그램 실행 시 명령어로 전달되는 문자열을 담습니다.

예시로 명령 프롬프트나 터미널에서 Java 프로그램을 다음과 같이 실행할 때:

java MyProgram Java is Fun

args에는 {"Java", "is", "Fun"}이라는 값이 전달됩니다.

public class MyProgram {
    public static void main(String[] args) {
        for (String arg : args) {
            System.out.println(arg);
        }
    }
}

이 프로그램은 각각의 단어를 출력합니다:

Java
is
Fun

 


Java의 참조 타입과 메모리 관리에 대한 개념을 이해하면 Java의 동작 원리를 보다 정확히 파악할 수 있습니다. 특히, 참조 타입이 실제 데이터가 아니라 주소를 저장한다는 개념과 Java 메모리 구조에 대한 이해는 앞으로의 학습과 개발에 큰 도움이 될 것입니다.