Technical Note/SERVER PERFORMANCE

- JVM과  JVM의 가비지 컬렉터가 대부분의 메모리 관련 작업을 처리한다 해도 메모리 손실이 발생할 수 있음

- GC : 루트 객체 (스택, 정적필드, JNI 핸들 등에 대한 객체) 에서 오는 모든 참조를 반복적으로 추적한 다음, 접근 가능한 모든 객체를 활성 상태로 표시
이렇게 표시된 객체만 프로그램에서 조작할수 있으며, 다른 객체는 삭제됩니다. 안전을 위해서 GC는 삭제된 객체에 프로그램이 접근할 수 없도록 합니다

- 메모리 관리 기능이 자동으로 수행된다고 하더라도 프로그래머는 메모리 관리와 관련된 문제를 늘 염두해 두어야 한다. 
- 메모리 할당하고 비우는 작업은 항상 비용과 관련
- 객체를 너무 많이 생성한 프로그램은 객체를 적게 생성하는 프로그램보다 속도가 느림
- 이미 할당된 메모리를 비우는것을 잊어버릴 경우에도 메모리 손실이 발생
- 사용하지 않을 객체에 대한 참조를 계속 유지할 경우 이런 객체는 주변에 머물며, 멤모리를 계속 소모하게 되는데 GC는 이 객체가 더이상 사용되지 않을것임을 알수있는 방법이 없다.
- 객체에 대한 참조가 존재한다면, 그 객체는 당연히 활성 상태 일 것이고 따라서 삭제되지 않을것이다
- 객체의 메모리를 회수하려면 더이상 해당 객체에 접근할수없도록 해야 함
- 이를 위해서 전형적인 방법은 객체의 필드를  null로 설정하거나 객체를 컬렉션에서 제고하는것 

메모리 릭의 유형과 그 원인



--------------------------------------------------------------------
  1. memory 사용율은 어느정도 인가?
  2. gabage collection은 잘 작동하고 있는가?
  3. jvm 설정 정보가 적절한가?
  4. Memory Leak 이 발생하지는 않는가?
  5. 만약 Memory Leak이 발생하였다면, Native stack, Heap, Perm 중 어느 영역이 문제인가?
  6. 또한 Memory Leak의 원인은 무엇인가?
  7. Thread 상태가 어떤가?
JVM 모니터링 항목 

메모리 모니터링을 시작 한다고 하면 제일 먼저 보는 항목은 무엇일까?
> 메모리 할당 정보 --> 아! 이정도 Heap 사이즈를 할당했구나..
그렇다면 메모리가 문제없이 잘 처리하고 있는가 확인해 볼까?
> GC를 보자 
GC의 어떤것을 보아야 하는가? 
> Young 영역에서 Old 영역으로 언제 얼마나 이동을 하는가? /  Stop-the-World가 언제 일어나고 얼마 동안 일어나고 있는가?


모니터링 방법에는 접근 인터페이스에 따라 CUI와 GUI로 구분이 된다.
CUI : jstat, jps, jstatd / JVM 을 가동할 때 '-verbosegc' 라는 JVM 옵션을 이용
GUI : Jconsole, jvisualVM, VisualGC

jstat : GC 수행 정보, 클래스 로더 수행 정보, heap 영역의 크기 변화 등
jps : vmid 와 main 메서드 정보 등
-verbosegc 옵션  : 직관적으로 이해하기 쉬운 출력 결과를 GC가 발생할 때마다 보여 주기 때문에 개략적인 GC 정보를 모니터링할 때에는 아주 좋다.
Jmap : Obejct  누수를 찾을때 지정된 시점의 힙에 대한 덤프  --> 힙의 스냅샷 (-histo) 옵션 : 힙에서 강력하게 참조된 오브젝트에 대한 텍스트 히스토그램 생성

표 3 jstat과 -verbosegc 옵션 비교
 

jstat

-verbosegc 옵션

모니터링 대상

터미널에 로그인할 수 있는 머신에서 가동 중인 Java 애플리케이션이거나 jstatd를 통하여 네트워크로 연결할 수 있는 리모트 Java 애플리케이션

JVM 시작 옵션으로 -verbosegc를 지정한 Java 애플리케이션에 대해서만

출력 정보

힙 상태(사용량, 최대 크기, GC 횟수/시간 등)

New 영역과 Old 영역에 대한 GC 이전/이후 크기와 수행 시간

출력 시기

지정한 시간 간격마다

GC가 발생할 때마다

유용할 때

힙 영역의 크기 변화를 관찰할 때

한 번의 GC에 대한 효과


Jhat : 힙 데이터를 분석

java visualVM : oracle JDK 가 제공하는 GUI 프로파일링/모니터링 툴
visualVM : 홈페이지에서 직접 내려 받은 GUI 프로파일링/모니터링 툴

JConsol : JMX 기술을 이용한 툴
JMeter : JVMTI 기반 기술을 이용한 툴


---------------------------------------------------------------
  1. memory 사용율은 어느정도 인가?
  2. gabage collection은 잘 작동하고 있는가?
  3. jvm 설정 정보가 적절한가?
  4. Memory Leak 이 발생하지는 않는가?
  5. 만약 Memory Leak이 발생하였다면, Native stack, Heap, Perm 중 어느 영역이 문제인가?
  6. 또한 Memory Leak의 원인은 무엇인가?
  7. Thread 상태가 어떤가?



기준 HotSpot JVM 을 기준으로 할것임


JVM 모니터링 항목을 보안
1. JVM 모니터링 항목

일반적인 JVM 모니터링 항목

1. JVM 설정 정보는 어떤가?   -->  Jinfo, Java Process  확인  / Jconsole
   - Heap Size 는 얼마인가?
   - GC 알고리즘은 어떤것인가?
   - 어떤 옵션을 사용하고 있는가?

2. Memory 사용율을 어느 정도인가? -->  jstat  /Jconsole

3. gabage collection은 잘 작동하고 있는가? --> jstat, '-Xverbose:gc 라는 JVM 옵션 / Jconsole
   - Young 영역에서 Old 영역으로 언제 얼마나 자주 이동을 하는가? 
   - GC Time 이 얼마나 걸리는가?

4. Memory Leak 이 발생하지는 않는가? --> jstat, jmap, jhat / Jconsole
   - FGC시 old  영역이 줄어들지는 않는가?
   - 사용하지 않을 객체가 계속 참조되고 있지는 않는가?

5. Thread 상태가 어떤가? --> jstack / Jconsole


2. 모니터링 방법
모니터링 방법에는 접근 인터페이스에 따라 CUI와 GUI로 구분이 된다.
CUI : jstat, jps, jstatd / JVM 을 가동할 때 '-Xverbose:gc 라는 JVM 옵션을 이용 / jmap / jhat
GUI : Jconsole, jvisualVM, VisualGC

jmx를 기반으로 개발한 도구로 jconsole이 있는데
모니터링 항목은
1. threads : Live threads, peak threads, Thread 상태 
2. Classes : 현재 로딩된  class 수 
3. memory : 메모리 통계
4. GC
5. 운영체제 정보

5. 추가적으로 모니터링을 하고 싶은것 (위의 방법들로는 못하는것)
- 메모리 LEAK 을 실제로 발견하게 되면 손실의 원인을 찾아내기 위한 도구가 필요
- 이러한 도구들이 jvm의 정보를 수집하는 방법으로 사용하는 기술이 두가지가 있는데 jvmti 와 바이트코드 조작 이다.


6. 그럼 어떤 기술을 통해서 모니터링 해야 하는가

JMX/JVMTI