자바 참조 타입 1

Dear·2025년 5월 13일

TIL

목록 보기
20/74

💙 데이터 타입

기본 타입 : 정수 타입, 실수 타입, 논리타입
참조 타입 : 배열 타입, 열거 타입, 클래스, 인터페이스

기본 타입을 이용해서 선언된 변수는 실제 값을 변수 안에 저장하지만, 참조 타입인 배열, 열거, 클래스, 인터페이스를 이용해서 선언된 변수는 메모리의 번지를 값으로 갖는다. 번지를 통해 객체를 참조한다는 뜻에서 참조 타입이라고 부른다.

변수는 스택 영역에 생성되고, 객체는 힙 영역에 생성된다.

참조 타입 변수는 힙 영역에 생성된 객체의 번지(주소 값)를 가져온다.

💙 메모리 사용 영역

java.exe로 JVM이 시작되면 JVM은 운영체제에서 할당받은 메모리 영역(Runtime Data Area)을 다음과 같이 세부 영역으로 구분해서 사용한다

변수는 스택 영역에 생성
객체와 배열은 힙 영역에 생성
→ 참조 타입 변수는 힙 영역에 생성된 객체나 배열의 번지(주소 값)을 가져온다

메소드 영역

코드에서 사용되는 클래스(~.class)들을 클래스 로더로 읽어 클래스별로 런타임 상수풀, 필드 데이터, 메소드 데이터, 메소드 코드, 생성자 코드 등을 분류해서 저장한다.

힙 영역

객체와 배열이 생성되는 영역이다. 힙 영역에 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다. 참조하는 변수나 필드가 없다면 JVM이 쓰레기 수집기(Garbage Collector)를 실행시켜 자동으로 제거

JVM 스택(Stack) 영역

JVM 스택 영역은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다. 추가적으로 스레드를 생성하지 않았다면 main 스레드만 존재하므로 JVM 스택도 하나이다. 스택은 메소드를 호출할 때마다 프레임(frame)을 추가(push)하고 메소드가 종료되면 제거(pop)한다. 프레임 내부에는 로컬 변수 스택이 있는데 변수가 이 영역에 생성되는 시점은 초기화 될 때, 즉 최초로 변수에 값이 저장될때이다. 선언된 블록에서만 변수가 존재한다. 벗어나면 스택에서 제거된다.

💙 참조 변수 ==, != 연산

기본 타입 변수의 ==, != 연산은 변수의 값이 같은지를 조사하지만 참조 타입 변수들 간의 연산은 동일한 객체를 참조하는지를 알아볼 때 사용한다. 결국 힙 영역의 주소 값을 비교하는 것이 된다 동일한 주소 값을 갖고 있다는 것은 동일한 객체를 참조한다는 의미이다.

💙 String vs StringBuffer vs StringBuilder

String

String은 new 연산자를 통해 생성되면 인스턴스 메모리 공간이 절대 변하지 않으므로 +, concat과 같은 연산시 메모리의 내용이 변하는 것이 아니라 새로운 String 인스턴스가 생성된다.
-> 문자열 리터럴이 동일하다면 String 객체를 공유

String name1 = "짱구";
String name2 = "짱구";

// name1과 name2는 동일한 String 객체를 참조한다.
name1 == name2 // true

String name1 = new String "짱구";
String name2 = new String "짱구";

// name1과 name2는 서로 다른 String 객체를 참조한다.
name1 == name2 // false
name1.equals(name2) // true

이렇게 새로운 문자열이 만들어지면 기존의 문자열은 가비지 콜렉터에 의해 제거되는데 문자열 연산이 많아지는 경우 성능이 떨어진다.

하지만 불변하기 때문에 조회가 빠르고 멀티스레드 환경에서 동기화를 신경 쓸 필요가 없다.

String 객체를 참조하다가 null을 대입하면 더 이상 String 객체를 참조하지 않는다. 참조를 잃은 String 객체는 쓰레기 객체로 취급하여 메모리에서 자동 제거된다.

StringBuffer vs StringBuilder

StringBufferStringBuilder는 한 번만 만들고 메모리의 값을 변경시켜서 문자열을 변경한다. 문자열 연산이 자주 있을 때 사용하면 좋다.

StringBuffer은 멀티 스레드 환경에서 synchronize 키워드가 가능하므로 동기화가 가능하다.

StringBuilder는 동기화를 지원하지 않기 때문에 멀티 스레드 환경에서 적합하지 않다.

사용 용도 간단 정리

String : 문자열 연산이 적고, 멀티스레드 환경일 경우
StringBuffer : 문자열 연산이 많고, 멀티스레드 환경일 경우
StringBuilder : 문자열 연산이 많고, 단일스레드이거나 동기화를 고려하지 않아도 되는 경우

profile
친애하는 개발자

0개의 댓글