문서의 선택한 두 판 사이의 차이를 보여줍니다.
양쪽 이전 판 이전 판 다음 판 | 이전 판 | ||
java:memory [2017/02/07 22:35] kwon37xi [Heap Dump on OutOfMemoryError] |
java:memory [2022/01/26 14:47] (현재) kwon37xi [Default 값] |
||
---|---|---|---|
줄 2: | 줄 2: | ||
* [[java: | * [[java: | ||
* [[java: | * [[java: | ||
+ | * [[java: | ||
+ | * [[java: | ||
+ | * [[java: | ||
* [[http:// | * [[http:// | ||
+ | ===== 기본 Heap 메모리 설정 ===== | ||
+ | * https:// | ||
+ | * 장비 메모리에서 OS와 다른 애플리케이션이 사용하는 것을 제외하고 설정할 수 있다.(보통 2GB정도 남겨두고 나머지를 설정하면 될듯) | ||
+ | * 하지만 Lucene의 경우 off heap 메모리를 사용하기 때문에 ElasticSearch는 장비 메모리의 50%만 heap으로 설정함. off heap 사용시에 관련 사항 주의. | ||
+ | * 운영체제 메모리가 아무리 많아도 heap은 32GB를 넘기지는 않게 한다. 31GB 정도 추천 | ||
+ | * Linux 운영체제 swap 일어나는 것을 방지하기 위해 **swappiness=1** 로 조정한다. [[linux: | ||
+ | |||
+ | ===== Default 값 ===== | ||
+ | * 운영체제에 따라 Java 버전에 따라 또한 현재 실행하고 있는 시스템의 메모리 상황에 따라 기본 메모리 설정이 다를 수 있다. 아래 명령으로 확인 가능하다. | ||
+ | <code sh> | ||
+ | # java 7 이하 | ||
+ | java -XX: | ||
+ | # java 8 이상 | ||
+ | java -XX: | ||
+ | |||
+ | uintx InitialHeapSize | ||
+ | uintx MaxHeapSize | ||
+ | </ | ||
+ | * 혹은 Java 애플리케이션에서 확인도 가능하다. | ||
+ | <code java> | ||
+ | System.out.println(Runtime.getRuntime().maxMemory()); | ||
+ | </ | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * 기본 규칙(Java 11) | ||
+ | * Min : 물리 메모리의 1/64 | ||
+ | * Max : 물리 메모리의 1/4 | ||
===== 64Bit 운영체제에서 포인터 크기 ===== | ===== 64Bit 운영체제에서 포인터 크기 ===== | ||
* 64Bit 운영체제에서라도 64bit long이 아니라 기본적으로 32bit 포인터를 사용한다. | * 64Bit 운영체제에서라도 64bit long이 아니라 기본적으로 32bit 포인터를 사용한다. | ||
줄 43: | 줄 74: | ||
===== jhat ===== | ===== jhat ===== | ||
* 힙 덤프를 분석한다. | * 힙 덤프를 분석한다. | ||
- | * '' | + | * '' |
* 힘 덤프 파일의 크기가 클 경우 OOM 에러가 발생할 수 있으므로 '' | * 힘 덤프 파일의 크기가 클 경우 OOM 에러가 발생할 수 있으므로 '' | ||
* 메모리를 너무 많이 먹어서 실제로 제대로 실행하기 힘듬. | * 메모리를 너무 많이 먹어서 실제로 제대로 실행하기 힘듬. | ||
줄 96: | 줄 127: | ||
</ | </ | ||
+ | ===== Code로 heap dump 뜨기 ===== | ||
+ | * [[https:// | ||
+ | <code java> | ||
+ | import javax.management.MBeanServer; | ||
+ | import java.lang.management.ManagementFactory; | ||
+ | |||
+ | import com.sun.management.HotSpotDiagnosticMXBean; | ||
+ | |||
+ | /** | ||
+ | * 현재 Java Application의 Heap Dump를 뜨는 함수 | ||
+ | * @see <a href=" | ||
+ | */ | ||
+ | public class HeapDumper { | ||
+ | // This is the name of the HotSpot Diagnostic MBean | ||
+ | private static final String HOTSPOT_BEAN_NAME = | ||
+ | " | ||
+ | // field to store the hotspot diagnostic MBean | ||
+ | private static volatile HotSpotDiagnosticMXBean hotspotMBean; | ||
+ | |||
+ | /** | ||
+ | * Call this method from your application whenever you | ||
+ | * want to dump the heap snapshot into a file. | ||
+ | * | ||
+ | * @param fileName name of the heap dump file | ||
+ | * @param live flag that tells whether to dump | ||
+ | | ||
+ | */ | ||
+ | public static void dumpHeap(String fileName, boolean live) { | ||
+ | // initialize hotspot diagnostic MBean | ||
+ | initHotspotMBean(); | ||
+ | try { | ||
+ | hotspotMBean.dumpHeap(fileName, | ||
+ | } catch (RuntimeException re) { | ||
+ | throw re; | ||
+ | } catch (Exception exp) { | ||
+ | throw new RuntimeException(exp); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // initialize the hotspot diagnostic MBean field | ||
+ | private static void initHotspotMBean() { | ||
+ | if (hotspotMBean == null) { | ||
+ | synchronized (HeapDumper.class) { | ||
+ | if (hotspotMBean == null) { | ||
+ | hotspotMBean = getHotspotMBean(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // get the hotspot diagnostic MBean from the | ||
+ | // platform MBean server | ||
+ | private static HotSpotDiagnosticMXBean getHotspotMBean() { | ||
+ | try { | ||
+ | MBeanServer server = ManagementFactory.getPlatformMBeanServer(); | ||
+ | HotSpotDiagnosticMXBean bean = | ||
+ | ManagementFactory.newPlatformMXBeanProxy(server, | ||
+ | HOTSPOT_BEAN_NAME, | ||
+ | return bean; | ||
+ | } catch (RuntimeException re) { | ||
+ | throw re; | ||
+ | } catch (Exception exp) { | ||
+ | throw new RuntimeException(exp); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public static void main(String[] args) { | ||
+ | // default heap dump file name | ||
+ | String fileName = " | ||
+ | // by default dump only the live objects | ||
+ | boolean live = true; | ||
+ | // simple command line options | ||
+ | switch (args.length) { | ||
+ | case 2: | ||
+ | live = args[1].equals(" | ||
+ | case 1: | ||
+ | fileName = args[0]; | ||
+ | } | ||
+ | // dump the heap | ||
+ | dumpHeap(fileName, | ||
+ | } | ||
+ | } | ||
+ | </ | ||