Mission (2)
5장까지 총 23개의 연습문제가 있습니다. 이 중 한 문제를 골라 풀이과정을 작성해 주세요.
연습문제를 읽어 본다.
맘에 드는 연습 문제를 하나 고른다.
연습 문제를 풀고 해설과 참고 문헌을 자세히 쓴다.
일부 자바 개발자들은 어떤 객체를 사용한 다음에 반드시 그 객체를 가리켰던 변수를 NULL로 설정한다. 왜 이것이 좋은 생각일까? (p.177)
작성하고 있는 코드가 큰 프로그램(메서드)의 일부라면 가능한 모든 객체 사용 후 null을 할당해주어야한다.
예제 1 (null ❌)
public class GCTest {
private final static int ALLOC_SIZE = (int) (Runtime.getRuntime().maxMemory() * 0.50);
public void allocate() {
System.out.println("Before first allocation");
//가용한 메모리의 50% 를 allocate 라는 메서드의 첫번째 지역 변수인 b 에서 할당
byte[] b = new byte[ALLOC_SIZE];
System.out.println(b);
System.out.println("After first allocation");
System.out.println("Before second allocation");
//전혀 하지 않은 후, 두번째 지역변수인 b2 에서 다시 50% 를 할당
byte[] b2 = new byte[ALLOC_SIZE];
System.out.println(b2);
System.out.println("After second allocation");
}
public static void main(String[] args) {
new GCTest().allocate();
}
}
public static void main(String[] args) {
new GCTest().allocate();
}
예제 1 결과
Before first allocation
[B@7637f22
After first allocation
Before second allocation
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java_lab.GCTest.allocate(GCTest.java:19)
at java_lab.GCTest.main(GCTest.java:28)
메모리 부족 현상이 나타난다.
예를 들어, 여러 스레드가 동작하여 각각 메서드를 실행하는데, 메서드가 아래와 같은 구조라면,
메서드 호출 ➡️ 객체 여러 개 생성 ➡️ 객체 사용 (이후에는 사용 안함) ➡️ 블럭되는 I/O처리 ➡️ 반환
메서드가 종료되기 전까지 참조하며 사용되지 않는 지역변수들이 쌓이게 된다. 결국 메모리 부족으로 GC가 수행되더라도 OOM(Out Of Memory)가 발생하게 된다.
예제 2 (null ⭕)
public class GCTest2 {
private final static int ALLOC_SIZE = (int) (Runtime.getRuntime().maxMemory() * 0.50);
public void allocate() {
System.out.println("Before first allocation");
byte[] b = new byte[ALLOC_SIZE];
System.out.println("After first allocation b : " + b);
b = null;
System.out.println("After assign null to b : " + b);
System.out.println("Before second allocation b : " + b);
byte[] b2 = new byte[ALLOC_SIZE];
System.out.println("After second allocation b2 : " + b2);
}
public static void main(String[] args) {
new GCTest2().allocate();
}
}
예제 2 결과
Before first allocation
After first allocation b : [B@7637f22
After assign null to b : null
Before second allocation b : null
After second allocation b2 : [B@4926097b
OOM이 발생하지 않는다.
그 외 아래의 참고를 통해 추가로 알게된 것!
null 할당은 GC 가 실행되면 바로 값을 회수해가버리고 이후에 해당 객체를 더이상 사용할 수 없지만,
라는 요구사항을 해결하기 위해 ver 1.2에서 나온 새로운 클래스가 java.lang.ref 패키지이다.
Reference, PhantomReference, SoftReference, WeakReference, ReferenceQueue
java.lang.ref 클래스에는 위의 5가지 클래스가 있다.
https://js2prince.tistory.com/entry/Java-객체-사용후-null-할당-해야하나-말아야-하나
변수를 NULL로 설정하면 그 변수가 가리켰던 객체를 가리키는 포인터의 수가 하나로 줄어든다. 포인터 개수가 0이 되면 그 객체는 가비지 컬렉션 대상이 된다.
실행 시간이 길어서 메모리 사용량이 시간이 지남에 따라 늘어나지도 않도록 신경 써야 하는 프로그램이라면 변수 NULL을 설정하는 것이 중요할 수 있다.