2014-11-19 3 views
3

충분한 여유 공간이 있어도 java.lang.OutOfMemoryError 오류가 발생합니다. 내가 사용한 메모리 덤프는 200MB에서 1GB 사이 였고 서버에는 24GB의 RAM이있었습니다. 나는 -Xmx12288m -Xms12288m을 설정했습니다. 내 개발자 머신 (충분한 여유 메모리가 있더라도 OutOfMemoryError

import org.snmp4j.Snmp; 
import org.snmp4j.transport.DefaultUdpTransportMapping; 

    long n = 0; 
    while (true) { 
     DefaultUdpTransportMapping transport = null; 
     try { 
      transport = new DefaultUdpTransportMapping(); 
      transport.listen(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
//  } finally {    // (*) I forgot this 
//   transport.close(); // (*) I forgot this 
     } 

     n++; 
     double freeMemMB = Runtime.getRuntime().freeMemory()/1024/1024; 
     System.out.println("Created " + n 
       + " DefaultUdpTransportMappings. Free Mem (mb): " 
       + freeMemMB); 
    } 

출력 : 내가 서버에 로그인하려고하면 아래의 코드로 좁혀

-bash: fork: retry: Resource temporarily unavailable 
-bash: fork: retry: Resource temporarily unavailable 
-bash: fork: retry: Resource temporarily unavailable 
-bash: fork: retry: Resource temporarily unavailable 
-bash: fork: Resource temporarily unavailable 

또한, 나는 자주 얻을) mvn exec:java로 :

Created 2026 DefaultUdpTransportMappings. Free Mem (mb): 299.0 
Created 2027 DefaultUdpTransportMappings. Free Mem (mb): 299.0 
[WARNING] 
java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.OutOfMemoryError: unable to create new native thread 
    at java.lang.Thread.start0(Native Method) 
    at java.lang.Thread.start(Thread.java:714) 
    at org.snmp4j.util.DefaultThreadFactory$WorkerThread.run(DefaultThreadFactory.java:91) 
    at org.snmp4j.transport.DefaultUdpTransportMapping.listen(DefaultUdpTransportMapping.java:168) 
    at App.main(App.java:19) 
    ... 6 more 

나는 닫지 일을하기 때문에 내가 오류를 얻을 것을 발견 e DefaultUdpTransportMapping. finally { ... } 블록을 사용하면 문제가 해결됩니다. 이제 나는 어떤 한계 (사용 가능한 메모리의 양이 아닌지)에 도달했는지 궁금합니다. 서버에 ulimit 값은 다음과 같습니다 내 개발자 맥에

core file size   (blocks, -c) 0 
data seg size   (kbytes, -d) unlimited 
scheduling priority    (-e) 0 
file size    (blocks, -f) unlimited 
pending signals     (-i) 191968 
max locked memory  (kbytes, -l) 64 
max memory size   (kbytes, -m) unlimited 
open files      (-n) 1024 
pipe size   (512 bytes, -p) 8 
POSIX message queues  (bytes, -q) 819200 
real-time priority    (-r) 0 
stack size    (kbytes, -s) 10240 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) 1024 
virtual memory   (kbytes, -v) unlimited 
file locks      (-x) unlimited 

는 :

-t: cpu time (seconds)    unlimited 
-f: file size (blocks)    unlimited 
-d: data seg size (kbytes)   unlimited 
-s: stack size (kbytes)    8192 
-c: core file size (blocks)   0 
-v: address space (kbytes)   unlimited 
-l: locked-in-memory size (kbytes) unlimited 
-u: processes      709 
-n: file descriptors    2560 

어떤 제한 I에 도달 했습니까?

+3

'-Xmx'는 무엇으로 설정되어 있습니까? –

+0

지역적으로, 나는'-Xmx1024m'을 가지고있다. '-Xmx2048m'으로 설정하면, 2027 DefaultUdpTransportMappings이 시작된 후에도 여전히 OutOfMemoryError가 발생합니다. 서버의 생산 과정에서'-Xmx12288m -Xms12288m'을 설정했습니다. 생산 프로세스의 메모리 덤프는 58MB입니다. –

+2

을 다시 실행하고 jconsole (jdk와 함께 제공됨)을 실행중인 프로세스에 첨부하십시오. Visual gc 플러그인을 추가하면 각 힙 영역의 할당 크기와 양이 표시됩니다. –

답변

0

java.lang.OutOfMemoryError: unable to create new native thread은 실제로 힙 메모리가 부족한 것과 관련이 없으므로 혼란스러운 메시지입니다. 따라서 힙 크기 설정 (Xmx 및 Xms)은이 경우 영향을 미치지 않습니다. 최대 개수의 프로세스 또는 열린 파일 핸들에 도달했거나 시스템에 새 스레드 생성 메모리가 남아 있지 않기 때문에 응용 프로그램에 대해 새 운영 프로세스를 만들 수없는 경우 예외가 발생합니다.

ulimit 설정은 파일 설명자 수, 스택 크기 또는 프로세스 수 중 하나 일 수 있습니다. 스택 크기는 스레드 당 숫자이며, 스레드 수와 스택 크기는 사용 된 메모리의 양이됩니다.

일반적으로이 예외가 발생하면 응용 프로그램이 스레드를 제대로 닫지 않고 시스템 프로세스를 계속 유지합니다. 이것이 trasnport를 닫으면이 문제가 해결되었습니다.