2011-02-15 4 views
2

자바 서버가 계속해서 충돌하기 시작했는데 이유를 찾을 수 없습니다.Java 충돌 응용 프로그램 - Java 충돌 원인을 찾는 방법?

저는 7.5GB 메모리가있는 서버가 있으며 Java 프로세스를 위해 3GB를 할당했습니다.

서버가 정상적으로 실행되고 가비지 수집을 여러 번 실행했지만 메모리 부족시 JVM이 손상되었습니다. 그것을 내가 GC의 실행 후 0.5 GB가

Current heap size:  
2 958 868 kbytes 
Maximum heap size:  
3 066 816 kbytes 
Committed memory:  
3 066 816 kbytes 
Pending finalization:  
0 objects 
Garbage collector:  
Name = 'PS MarkSweep', Collections = 66, Total time spent = 7 minutes 
Garbage collector:  
Name = 'PS Scavenge', Collections = 43 055, Total time spent = 44 minutes 



Operating System:  
Linux 2.6.31-302-ec2 
Architecture:  
amd64 
Number of processors:  
2 
Committed virtual memory:  
8 405 760 kbytes 
Total physical memory:  
7 882 780 kbytes 
Free physical memory:  
   34 540 kbytes 
Total swap space:  
        0 kbytes 
Free swap space:  
        0 kbytes 

, 그래서 모든 시간은 0.5 3 GB에 0.5로 다시 하락보다 상승 : 여기

는 충돌 후 JConsole의에서 정보입니다 매달려있는 물건에 절대적으로 문제가되지 않습니다. 실제로 그것은 충돌 대신 OutOfMemoryException을 던져야합니다. 해당 매개 변수를 사용하고 있습니다.

-Xmn256m -Xms768m -Xmx3000m -XX:NewRatio=2 -server -verbosegc -XX:PermSize=256m -XX:MaxPermSize=256m -XX:SurvivorRatio=8 -XX:+UseParallelGC -XX:ParallelGCThreads=2 -XX:+UseParallelOldGC 

무엇이 잘못 되었습니까? 표시된 출력은 다음과 같습니다.

Current thread (0x00007fe899755800): JavaThread "[email protected]" [_thread_in_vm, id=11941, stack(0x00007fe86a4e5000,0x00007fe86a5e6000)] 

siginfo:si_signo=SIGSEGV: si_errno=0, si_code=128(), si_addr=0x0000000000000000 

Registers: 
RAX=0x00007fe9c60333b8, RBX=0x00007fe899755800, RCX=0x0d00007fe8f58787, RDX=0x00007fe9c6031888 
RSP=0x00007fe86a5e3fd0, RBP=0x00007fe86a5e4020, RSI=0x00007fe899755800, RDI=0x00007fe95bae1770 
R8 =0x00007fe9be341620, R9 =0x0000000000000001, R10=0x00007fe9c5b84460, R11=0x00007fe9c051a52b 
R12=0x00007fe9c051a529, R13=0x00007fe9c6034ac0, R14=0x00007fe9c051a599, R15=0x0900007fe8f58787 
RIP=0x00007fe9c5bd562d, EFL=0x0000000000010246, CSGSFS=0x000000000000e033, ERR=0x0000000000000000 
    TRAPNO=0x000000000000000d 

Stack: [0x00007fe86a4e5000,0x00007fe86a5e6000], sp=0x00007fe86a5e3fd0, free space=3fb0000000000000030k 
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) 
V [libjvm.so+0x64d62d] 
V [libjvm.so+0x5fc4df] 

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) 
v ~RuntimeStub::_complete_monitor_locking_Java 
J sun.nio.ch.SocketChannelImpl.write(Ljava/nio/ByteBuffer;)I 
J org.mortbay.io.nio.ChannelEndPoint.flush(Lorg/mortbay/io/Buffer;)I 
J org.mortbay.jetty.HttpGenerator.flush()J 
... 
+0

JNI 구성 요소가 있습니까? –

+0

당신이 GC를 여러 번하고 있다는 사실은 경고음을 설정해야합니다. 어떤 GC도하지 않고 JVM을 사용하여 최상의 성능을 발휘한다면 서버의 행동은 무엇입니까? – anirvan

+0

어떤 프로그램이 실행되고 있습니까? Java는 자체적으로 가비지 콜렉션을 수행하지만 프로그램에서 메모리 누수가 발생하면 충분하지 않을 수 있습니다. –

답변

0

소리가 메모리 누수와 같습니다. gc는 더 이상 참조되지 않는 객체 만 정리할 수 있습니다. 그리고 응용 프로그램 (또는 서버 자체)이 사용하지 않는 자원을 "비어 있지 않으면"잠시 후에 3GB도 충분하지 않습니다.

프로필러는 예기치 않게 커지는 데이터 구조를 식별하는 데 도움이 될 수 있습니다.


아이디어 : -verbose:gc 옵션으로 서버를 시작하고 죽기 직전에 확인하십시오. 테스트를 위해 힙 공간을 줄이면 오래 기다릴 필요가 없습니다. 메모리 누수가있는 경우 gc가 실행될 때마다 메모리를 덜 확보 할 수있는 정규 gc주기를 볼 것으로 기대합니다.


업데이트는

나는 outofmemoryerror 태그로 오해했다. 사실 JVM 충돌이며 설치된 Java를 업데이트하려고합니다. 이미 1.6.0_17 및 1.6.0_18 (like this question on SO) 빌드의 "SIGSEGV (0xb)"충돌에 대한 보고서가 있습니다.

이것은 JVM 내부 문제입니다.

+0

그런 다음 jmap 및 jhat로 전환하여 누출을 진단하십시오. – andersoj

+0

아니, 청소해야 할 쓰레기. 나는 기가 바이트를 실행 한 후에 항상 0.5GB의 데이터를 가지고 있으므로 항상 0,5에서 3GB로 올리고 0,5로 떨어지는 것보다 매달려있는 객체에 대해서는 전혀 문제가되지 않습니다. 사실 그것은 충돌과 예외가 아닌 OutOfMemoryException을 던질 수 있습니다. 나는 그 매개 변수들을 사용하고있다. -Xmn256m -Xms : NewRatio = 2 -server -verbosegc -XX : PermSize = 256m -XX : MaxPermSize = 256m -XX : SurvivorRatio = 8 -XX : + UseParallelGC -XX : ParallelGCThreads = 2 -XX : + UseParallelOldGC –

+0

신뢰할 수있는 구성이 작동 할 때까지 JVM 매개 변수를 수정하지 말 것을 강력히 권장합니다! 또한이 정보는 귀하의 질문에 반드시 포함되어야합니다. –

0

"메모리 문제"가있는 경우 실제 하드웨어에 결함이 있는지 걱정할 필요가있는 경우 스트레스 테스트를 강력히 고려해야합니다.

전통적인 PC의 경우 일반적으로 memtest86을 사용합니다. 최신 버전은 다음에서 볼 수 있습니다. http://www.memtest.org/

메모리가 memtest86으로 철야 검사를 통과하면 올바르게 작동하는지 확실하게 알 수 있습니다.

+0

오래된 가상 컴퓨터에 결함이 있으므로 아마존 서버를 사용하고 있습니다. 새 일회용 컴퓨터가 도움이되기를 바랍니다. 그것은 절대적으로 하드웨어 문제가 아닙니다. 그것은 단지 자바 문제가 아니라면, 그것은 자바 문제가 될 수 있습니다. –

+0

좋다. 그렇다면 그 것이 명확해진다. JDK의 jvisualvm을 살펴보면 실행중인 애플리케이션을 프로파일 링 할 수 있으므로 메모리 누수를 찾아야합니다. –

0

JVM에 3GB를 할당했다고하면이 크기가 힙 크기 또는 전체 크기 (상당히 더 클 수 있습니다)입니다. 3GB 힙을 가진 JVM은 총 4GB까지 clsoe를 사용할 수 있습니다. JVM이 GC로 추락 한 경우

, 내가 자바 6 업데이트처럼 당신의 JVM의 현재 버전을 확인할 것 (23)

충돌은 무엇입니까?때로는 다른 사용자가 동일한 오류를보고하고 Google에서 오류를 일으킬 수 있습니다. 때로는 제안 된 솔루션이 있습니다.

+0

나는 3GB 만 할당했고, 4,5Gb를 무료로 사용할 수있어 총 7,5GB가되었습니다. 그것은 무료 momemory, 리눅스에서 실행되는 다른 큰 proceses입니다. –

+0

또한 자바 5, 자바 6 최신 하나, OpenJDK 최신 하나, 항상 같은 결과를 사용. JVM은 매번 크래쉬 파일을 생성하지는 않습니다. 오류 파일의 예는 다음에서 찾을 수 있습니다. http://chessfriends-release.s3.amazonaws.com/logs/hs_err_pid10930.log?AWSAccessKeyId=AKIAJP5BYGKOCMCDVZHA&Expires=1301375337&Signature=t%2BGbqACiaF7qHJJmR3881dmLQeI%3D –

+0

Java 6 업데이트 18이 안정적임을 발견했습니다. . 하지만 훨씬 더 새로운 JVM을 사용하는 23 또는 24의 업데이트를 시도해 볼 가치가 있습니다. (AFAIK 이상) –

1

링크 된 충돌 문서에서 오류는 네이티브 메모리에 대한 읽기/쓰기 오류 인 SIGSEGV입니다. 스레드 스택이 JVM 코드에서 오류를 표시합니다.

Current thread (0x00007fe899755800): JavaThread "[email protected]" [_thread_in_vm, id=11941, stack(0x00007fe86a4e5000,0x00007fe86a5e6000)] 

siginfo:si_signo=SIGSEGV: si_errno=0, si_code=128(), si_addr=0x0000000000000000 

Registers: 
RAX=0x00007fe9c60333b8, RBX=0x00007fe899755800, RCX=0x0d00007fe8f58787, RDX=0x00007fe9c6031888 
RSP=0x00007fe86a5e3fd0, RBP=0x00007fe86a5e4020, RSI=0x00007fe899755800, RDI=0x00007fe95bae1770 
R8 =0x00007fe9be341620, R9 =0x0000000000000001, R10=0x00007fe9c5b84460, R11=0x00007fe9c051a52b 
R12=0x00007fe9c051a529, R13=0x00007fe9c6034ac0, R14=0x00007fe9c051a599, R15=0x0900007fe8f58787 
RIP=0x00007fe9c5bd562d, EFL=0x0000000000010246, CSGSFS=0x000000000000e033, ERR=0x0000000000000000 
    TRAPNO=0x000000000000000d 

Stack: [0x00007fe86a4e5000,0x00007fe86a5e6000], sp=0x00007fe86a5e3fd0, free space=3fb0000000000000030k 
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) 
V [libjvm.so+0x64d62d] 
V [libjvm.so+0x5fc4df] 

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) 
v ~RuntimeStub::_complete_monitor_locking_Java 
J sun.nio.ch.SocketChannelImpl.write(Ljava/nio/ByteBuffer;)I 
J org.mortbay.io.nio.ChannelEndPoint.flush(Lorg/mortbay/io/Buffer;)I 
J org.mortbay.jetty.HttpGenerator.flush()J 
<snip> 

JVM 버그이거나 메모리 손상 일 수 있습니다.