문서의 선택한 두 판 사이의 차이를 보여줍니다.
| 양쪽 이전 판 이전 판 다음 판 | 이전 판 | ||
|
java:memory [2015/11/15 14:25] kwon37xi [참조] |
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 long이 아니라 기본적으로 32bit 포인터를 사용한다. | ||
| + | * 그러나 Heap 사이즈가 **대략 32GB**가 넘어가면 그때부터 64bit 포인터로 바뀐다. 이렇게 되면 포인터 자체가 차지하는 메모리가 너무 커서 낭비적이 될 수 있다. | ||
| + | * 일반적으로 Heap Size가 31GB 정도일 때 32bit 압축 포인터가 거의 확실하게 사용된다. 그 이상일 때는 운영체제 환경, JDK 종류/ | ||
| + | * [[java: | ||
| ===== Heap Dump on OutOfMemoryError ===== | ===== Heap Dump on OutOfMemoryError ===== | ||
| 줄 37: | 줄 74: | ||
| ===== jhat ===== | ===== jhat ===== | ||
| * 힙 덤프를 분석한다. | * 힙 덤프를 분석한다. | ||
| - | * '' | + | * '' |
| * 힘 덤프 파일의 크기가 클 경우 OOM 에러가 발생할 수 있으므로 '' | * 힘 덤프 파일의 크기가 클 경우 OOM 에러가 발생할 수 있으므로 '' | ||
| * 메모리를 너무 많이 먹어서 실제로 제대로 실행하기 힘듬. | * 메모리를 너무 많이 먹어서 실제로 제대로 실행하기 힘듬. | ||
| 줄 90: | 줄 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, | ||
| + | } | ||
| + | } | ||
| + | </ | ||