by fienestar
var a = new Integer(10); var b = a; System.out.println(a); a = null; // 아직 객체는 참조되는중 b = null; // 더 이상 해당 객체는 참조되지 않음
컴파일 타임에 언제 삭제되는지 아는 경우 그 위치에 메모리 해제 코드를 삽입
{ A a = new A; // ++ } // --
참조중인 변수의 lifecycle이 종료되는 시점에 참조카운트--, 참조하기 시작할때 ++ 카운트가 0이 되면, 자원 해제
// ref_count는 컴파일러에 의해 생긴 코드 public void f(A a){ a.ref_count += 1; // use a a.ref_count -= 1; if(a.ref_count == 0) remove(a) } public static void main(String[] args) { A a; // default value of A::ref_count = 1 f(a) a.ref_count -= 1; if(a.ref_count == 0) remove(a) }
순환 참조 문제
b.m = a a.m = b
동시성 문제
공간 비용
어떤 스레드에 의해 직/간접적으로 참조되고 있다
// low high // // +-- generation boundary // | (fixed after startup) // |<- Young gen (reserved MaxNewSize) ->|<- Old gen (reserved MaxOldSize) ->| // +-----------+--------+--------+--------+---------------+-------------------+ // | eden | from | to | | old | | // | | (to) | (from) | | | | // +-----------+--------+--------+--------+---------------+-------------------+ // |<- committed ->| |<- committed ->|
계속 다른 Suvivor 로 이동하는 이유는, 메모리 단편화를 완화하기 위해서이다. 2번과정을 aging이라 부른다.
gc 시간 비율(세로), 프로세서 수(가로)
XX:+UseSerialGC
XX:+UseParallelGC
-XX:+UseG1GC
-XX:UseZGC
-Xms{size}
-Xmx{size}
-XX:NewRaito
-XX:NewSize
-XX:Survivor Raito
메모리가 여유로우면 유지하고,부족하면 제거해도 좋을때 => 있으면 좋지만 없어도 로직상 문제가 되지 않는 객체 ex) 캐시 등
var softRef = new SoftReference<T>(new T()); var weakRef = new WeakReference<T>(new T()); // var phantomRef = new PhantomReference<T>(new T(), ...); T ref; ref = softRef.get(); ref = weakRef.get();