2017-12-13 124 views
3

세 가지 JVM 이외의 추가 실행없이 최소한의 설치로 빌드 된 64 비트 Ubuntu VM에서 Java 8 JVM 3 개를 실행하고 있습니다. VM 자체에는 2GB의 메모리가 있으며 각각의 JVM은 -Xmx512M으로 제한되어 있습니다.Java 8 메모리 사용 제한

몇 주 전, 하나는 추락하고 hs_err_pid 덤프 보여 주었다 :

# There is insufficient memory for the Java Runtime Environment to continue. 
# Native memory allocation (mmap) failed to map 196608 bytes for committing reserved memory. 
# Possible reasons: 
# The system is out of physical RAM or swap space 
# In 32 bit mode, the process size limit was hit 
# Possible solutions: 
# Reduce memory load on the system 
# Increase physical memory or swap space 
# Check if swap backing store is full 
# Use 64 bit Java on a 64 bit OS 
# Decrease Java heap size (-Xmx/-Xms) 
# Decrease number of Java threads 
# Decrease Java thread stack sizes (-Xss) 
# Set larger code cache with -XX:ReservedCodeCacheSize= 
# This output file may be truncated or incomplete. 

나는 3백84메가바이트의 감소 힙 크기의 JVM을 다시 시작하고 지금까지 모든 것이 괜찮습니다. 나는 현재 ps 명령을 사용하여 VM을보고 일종의 RSS 크기를 내림차순으로 내가

RSS %MEM VSZ PID CMD 
708768 35.4 2536124 29568 java -Xms64m -Xmx512m ... 
542776 27.1 2340996 12934 java -Xms64m -Xmx384m ... 
387336 19.3 2542336 6788 java -Xms64m -Xmx512m ... 
12128 0.6 288120 1239 /usr/lib/snapd/snapd 
4564 0.2 21476 27132 -bash 
3524 0.1 5724 1235 /sbin/iscsid 
3184 0.1 37928  1 /sbin/init 
3032 0.1 27772 28829 ps ax -o rss,pmem,vsz,pid,cmd --sort -rss 
3020 0.1 652988 1308 /usr/bin/lxcfs /var/lib/lxcfs/ 
2936 0.1 274596 1237 /usr/lib/accountsservice/accounts-daemon 
.. 
.. 

을 볼 수 있고 무료 명령

   total  used  free  shared buff/cache available 
Mem:   1952  1657   80   20   213   41 
Swap:    0   0   0 

예로 들어 첫 번째 프로세스를 복용 보여줍니다 그러나 때,이입니다 힙 제한은 524288KB (512 * 1024)이지만 RSS 크기는 708768KB입니다.

JVM 힙에 여분의 메모리가 사용된다는 사실을 알고 있습니다 만, 메모리를 다시 사용하지 않도록 어떻게 제어 할 수 있습니까? 내가 JVM을 붕괴하지 않고 가능한 한 큰 JVM의 힙 크기를 설정하려고합니다.

또는 전체 메모리 가용성과 관련하여 JVM 힙 크기를 설정하는 방법에 대한 일반적인 지침이 있습니까?

+0

제한을 설정해도 JVM의 메모리가 부족하지는 않습니다. 애플리케이션에 메모리가 필요하다면 변경하려는 것은 * JVM의 메모리가 부족합니다. – Holger

+0

응용 프로그램에 메모리가 "필요"하다고 생각하지 않습니다.512MB로 크래시 된 Java 응용 프로그램은 다시 시작할 때 384MB로 정상적으로 실행됩니다. 그것은 마치 512MB 한도 내에서 메모리를 할당하려했기 때문에 추락 한 것처럼 보이지만 그 메모리는 거기에 없었습니다 (다른 JVM 중 하나 또는 둘 다 512MB보다 잘 사용했기 때문에 거기에 없었습니다). 힙을 384MB로 줄이면 가비지 수집기 (및 프로세서)가 더 활성화 될 수 있지만 존재하지 않는 메모리는 찾지 않습니다. – paulh

+1

-Xmx 설정은 JVM 힙에 대한 제어 만 가지고 있지만 오류 표시로 기본 메모리가 부족합니다. 원시 메모리와주의해야 할 사항에 대해 더 자세히 읽으십시오 - https://www.ibm.com/developerworks/java/library/j-nativememory-linux/ – Fairoz

답변

0

JVM이 힙에서 사용할 여분의 메모리 양을 제어하는 ​​방법이없는 것 같습니다. 그러나 일정 기간 동안 응용 프로그램을 모니터링하면이 양을 잘 예측할 수 있습니다. Java 프로세스의 전체 소비가 원하는 것보다 높으면 힙 크기를 줄일 수 있습니다. 이것이 성능에 영향을 미치는지 보려면 추가 모니터링이 필요합니다.

위의 예를 계속하고 PID, cmd를 --sort -rss 우리가 오늘로 사용을 참조 RSS, pmem, VSZ, -o 명령 PS 도끼를 사용하여

RSS %MEM VSZ PID CMD 
704144 35.2 2536124 29568 java -Xms64m -Xmx512m ... 
429504 21.4 2340996 12934 java -Xms64m -Xmx384m ... 
367732 18.3 2542336 6788 java -Xms64m -Xmx512m ... 
13872 0.6 288120 1239 /usr/lib/snapd/snapd 
.. 
.. 

이 자바 프로세스입니다 모두 동일한 응용 프로그램을 실행하지만 다른 데이터 세트로 실행됩니다. 첫 번째 프로세스 (29568)는 힙 한계를 초과하여 약 190M을 사용하여 안정적으로 유지되었으며 두 번째 프로세스 (12934)는 156M에서 35M으로 감소했습니다. 세 번째 메모리의 총 메모리 사용량은 힙 크기를 유지하면서 힙 한도를 줄일 수 있음을 나타냅니다.

Java 프로세스 당 200MB의 힙이 아닌 200MB의 메모리를 허용하는 것이 600MB의 여유 공간을 제공 할만큼 충분할 것으로 보입니다. 2GB에서이 값을 뺀 값이 1400MB이므로 세 개의 -Xmx 값을 합한 값이이 값보다 작아야합니다.

Fairoz의 의견에서 지적한 기사를 읽고 나면 JVM이 비 힙 메모리를 사용할 수있는 여러 가지 방법이 있습니다. 측정 가능한 스레드 중 하나는 스레드 스택 크기입니다. JVM의 기본값은 리눅스에서 java -XX를 사용하여 찾을 수 있습니다 : + PrintFlagsFinal -version | grep ThreadStackSize 위의 경우 1MB이고 약 25 개의 스레드가 있으므로 적어도 25MB의 여분이 항상 필요하다고 안전하게 말할 수 있습니다.