자바 가상 머신(JVM)은 효율적인 자원 관리를 위해 메모리를 여러 영역으로 나눕니다. 각 영역의 특징을 이해하는 것이 성능 최적화와 디버깅의 첫걸음입니다.
static 변수, 상수(final) 등이 저장됩니다. 프로그램 시작 시 로드되는 '설계도' 보관소라고 생각하면 쉽습니다.new 키워드로 생성된 실제 객체 인스턴스와 배열이 저장됩니다. 가비지 컬렉터(GC)가 주기적으로 방문하여 쓰이지 않는 객체를 치워주는 '실제 물건' 창고입니다.잠깐! PC 레지스터는 무엇인가요?
현재 실행 중인 명령어의 주소를 저장하여 프로그램 실행 흐름을 제어하는 역할을 합니다.
static이 붙은 멤버(필드, 메서드)는 객체 생성 없이도 클래스 이름으로 바로 접근할 수 있습니다.
static은 프로그램 시작 시 이미 메모리에 있지만, 인스턴스 변수는 객체가 생성되어야 힙에 존재하기 때문입니다.데이터를 외부로부터 보호하는 캡슐화(Encapsulation)를 위해 접근 제한자를 적절히 사용해야 합니다.
| 제한자 | 범위 | 설명 |
|---|---|---|
| public | 전체 | 어디서든 접근 가능 |
| protected | 패키지 + 상속 | 동일 패키지 혹은 다른 패키지의 자식 클래스까지 |
| default | 패키지 | 동일 패키지 내에서만 가능 (생략 시 기본값) |
| private | 클래스 | 동일 클래스 내부에서만 가능 |
팁: 최상위 외부 클래스에는
public과default만 사용할 수 있습니다.
객체 배열을 다룰 때 가장 많이 실수하는 부분이 바로 참조(Reference) 개념입니다.
tmp = p;vsarr[i] = p;
데이터를 수정할 때 왜tmp를 쓰면 안 될까요?
- 잘못된 예:
Person tmp = arr[i]; tmp = newPerson;- 결과:
tmp라는 이름표만 새로운 객체를 가리키게 되고, 배열 칸(arr[i])이 가리키는 실제 데이터는 변하지 않습니다.
- 올바른 예:
arr[i] = newPerson;- 결과: 배열의 해당 칸 자체가 새로운 주소값을 가리키게 되어 수정이 반영됩니다.
배열 중간의 데이터를 삭제했다면, 빈 공간을 메우기 위해 데이터를 앞으로 당기는 과정이 필요합니다.
// 데이터를 삭제 후 뒤의 요소들을 한 칸씩 당김
for (int j = i; j < size - 1; j++) {
arr[j] = arr[j + 1];
}
arr[size - 1] = null; // 마지막 칸 비우기
size--; // 관리하는 데이터 개수 감소
클래스의 인스턴스를 단 하나만 생성하도록 보장하는 디자인 패턴입니다. 매니저 객체처럼 프로그램 전체에서 공유되어야 하는 '중앙 관리자' 역할에 주로 쓰입니다.
new를 못 하게 막습니다.getInstance()를 통해 유일한 객체를 반환합니다.static 멤버는 클래스 이름으로 접근하며 메모리에 미리 로드된다.protected는 패키지가 달라도 상속 관계라면 접근을 허용한다.arr[i])에 직접 새 객체를 대입해야 한다.private으로 숨기는 것이 핵심이다.