[Java] GC 에 대한 이야기 |
http://www.javaworld.com/article/2078645/java-se/jvm-performance-optimization-part-3-garbage-collection.html
-
System.gc() 를 호출하는 것이 GC 를 보장하지 않는다.
-
gc 가 호출되면 gc 는 자신이 실행되어도 안전한 시점인지 확인 후 실행된다.
안전한 시점이라는 것은 지속적인 object allocation 이 아닐 때, optimized CPU instruction 의 중간이 아닐 때 와 같은 경우가 있겠다.
-
GC 는 여러 가지 variation 이 있지만 다음 두가지는 모든 GC 가 동일하다.
1. OOM 이 나지 않도록 사용되지 않는 메모리를 free 시킨다.
2. performance 저하를 최소한으로 하면서 수행한다.
-
GC 에는 기본적으로 2가지 접근법이 있다.
하나는 reference counting 이고 다른 하나는 tracing collector 이다.
-
Reference Counting 방법은 바로 object 들에 접근해서 reference count 를 체크하여 free 시킬 수 있다는 장점이 있다.
하지만 모든 reference count 를 최신으로 유지하는 것은 매우 무거운 작업이다.
덧붙여 circular structure 의 경우를 다루기가 까다롭다.
이 circular structure 인지를 조사하는 과정이 또 엄청난 overhead 가 될 수 있다.
-
Tracing collectors 는 "모든 살아있는 object 들은 계속 reference 들을 따라가면 닿을 수 있다"는 데 있다.
기본 live object set 은 register, global fields, stack frame 들을 조사하여 알 수 있다.
이 기본 live object set 이 조사되면 이 녀석들을 쭉 따라가며 살아있다고 마킹을 한다.
한번 마킹이 끝나면 그 외의 나머지를 free 시킨다.
Tracing collector 는 circulr structure 를 판단하기도 쉽다.
-
Tracing collector 가 주로 쓰이는 GC 방법이다.
Commercial 로 쓰기에 적합하다고 이미 증명된 방법이다.
-
Copying 와 mark-and-sweep 가 tracing collector 에서 주로 쓰이는 가장 흔한 알고리즘이다.
-
Copying 방법은 tracing 을 하면서 from space 에서 to space 로 복사를 하고, from space 전체를 free 시킨다.
이전에는 메모리를 반으로 나누어 from space 와 to space 가 switching 되는 방식이었다.
새로운 방식은 메모리를 반으로 나누지 않고 특정 영역을 잡고 이 방법을 수행한다.
-
Copying 방법의 장점은 memory fragmentation 을 방지한다는 것이다.
Copying 방법의 단점은 stop-the-world collector 라는 것이다.
그래서 memory 를 많이 사용하면 할수록 performance 이슈는 더 잘 터져나온다.
덧붙여 copying 은 to space 의 영역에 copying 해야 하기 때문에 메모리 영역을 어느 정도 항상 확보해놔야 하고, 메모리 효율 면에서 조금 비효율적이다.
-
Mark-and-sweep collector 가 대부분의 commercial JVM 이 차용하고 있는 GC 방법이다.
mark-and-sweep 은 performance 에 영향을 주지 않는다.
가장 유명한 이 방식의 collector 는 CMS, G1, GenPar, DeterministicGC 등이 있다.
mark-and-sweep 은 bit 으로 marking 을 한다.
marking 이 끝나면 sweep 을 하기 전에 heap 전체를 다시 한번 순회하며 mark 안된 memory 를 free 시킨다.
collector 는 이 녀석들을 free list 에 모아놓는다.
chunk size 를 기준으로 나뉜 free list 가 gc 에 여러개가 있다.
sweep 이 끝나면 다시 allocation 을 시작할 수 있다.
새로운 allocation 영역은 fragmentation 을 막기 위해 free list 에 모아 놓은 녀석들 중 사이즈가 가장 비슷한 조금 더 큰 그릇에 할당한다.
mark는 heap 의 live data 의 양에 영향을 받고, sweep 은 heap size 에 영향을 받는다.
mark 와 sweep phase 가 끝날 때까지 기다려야 하기 때문에 큰 heap 이나 큰 live data set 에서는 꽤나 시간이 걸린다.
하지만 이 녀석은 어찌되었든 tuning 의 소지가 있다.
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[android] xml 의 tool 을 사용하자 (0) | 2017.05.30 |
---|---|
[android] LOS visibility change & ripple animation glitch (잔상문제) (0) | 2017.05.29 |
[android] CircularRevealEffect Basic Simple Example (0) | 2017.05.24 |
[android] Custom view state 관리에 대한 내용. (0) | 2017.05.23 |
[android] LinearLayoutManager 를 사용할 때 smooth scrolling 을 하게 하려면 (0) | 2017.05.22 |
댓글