소켓 파일을 열 수없는 jmap 실행


85

jmap내 프로세스의 힙 덤프를 가져 오기 위해 실행해야했습니다 . 그러나 jvm반환 :

Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding

그래서 나는 다음을 사용했습니다 -F.

./jmap -F -dump:format=b,file=heap.bin 10330
Attaching to process ID 10331, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.51-b03
Dumping heap to heap.bin ...
  1. -F 힙 덤프를 사용하는 것은 괜찮습니까?
  2. 20 분을 기다렸는데 아직 끝나지 않았습니다. 이유는 무엇입니까?

답변:


181

jmapjmap -F뿐만 아니라 jstack대를 jstack -F사용하는 완전히 다른 메커니즘은 목표 JVM과 communcate한다.

jmap / jstack

-F이러한 도구 없이 실행할 경우 동적 연결 메커니즘을 사용 합니다 . 이것은 다음과 같이 작동합니다.

  1. Java 프로세스 1234에 연결하기 전에, jmap파일 생성 .attach_pid1234대상 프로세스의 또는 작업 디렉토리에서를 /tmp.

  2. 그런 다음 대상 프로세스로 jmap보냅니다 SIGQUIT. JVM이 신호를 포착하고을 찾으면 스레드를 .attach_pid1234시작 AttachListener합니다.

  3. AttachListener스레드 /tmp/.java_pid1234는 외부 도구의 명령을 수신하기 위해 UNIX 도메인 소켓 을 만듭니다 .

  4. 연결 (에서 jmap)이 승인 될 때 보안상의 이유로 JVM은 소켓 피어의 신임 정보 가 JVM 프로세스 euid와 동일한 지 확인합니다 egid. 그렇기 때문에 jmap다른 사용자가 (루트에서도) 실행하면 작동하지 않습니다.

  5. jmap소켓에 연결하고 dumpheap명령을 보냅니다 .

  6. 이 명령은 AttachListenerJVM 스레드에서 읽고 실행합니다 . 모든 출력은 소켓으로 다시 전송됩니다. 힙 덤프는 JVM에서 직접 처리되므로 작업이 정말 빠릅니다. 그러나 JVM은 safepoints 에서만이를 수행 할 수 있습니다 . Safepoint에 도달 할 수없는 경우 (예 : 프로세스가 중단되거나 응답하지 않거나 긴 GC가 진행 중임) jmap시간이 초과되어 실패합니다.

Dynamic Attach의 장점과 단점을 요약 해 보겠습니다.

찬성.

  • 힙 덤프 및 기타 작업은 JVM에서 최대 속도로 공동으로 실행됩니다.
  • jmap또는의 모든 버전 jstack을 사용하여 다른 버전의 JVM에 연결할 수 있습니다 .

단점.

  • 도구는 대상 JVM과 동일한 사용자 ( euid/ egid) 가 실행해야합니다 .
  • 활성 상태의 정상 JVM에서만 사용할 수 있습니다.
  • 대상 JVM이로 시작되면 작동하지 않습니다 -XX:+DisableAttachMechanism.

jmap -F / jstack -F

-F도구를 사용 하여 실행하면 HotSpot Serviceability Agent 기능이있는 특수 모드로 전환됩니다 . 이 모드에서는 대상 프로세스가 고정됩니다. 도구 ptrace는 Linux에서 OS 디버깅 기능을 통해 메모리를 읽습니다 .

  1. jmap -FPTRACE_ATTACH대상 JVM에서 호출합니다 . 대상 프로세스는 SIGSTOP신호 에 응답하여 무조건 중단됩니다 .

  2. 이 도구는를 사용하여 JVM 메모리를 읽습니다 PTRACE_PEEKDATA. ptrace한 번에 한 단어 만 읽을 수 있으므로 대상 프로세스의 큰 힙을 읽는 데 너무 많은 호출이 필요합니다. 이것은 매우 느립니다.

  3. 이 도구는 특정 JVM 버전에 대한 지식을 기반으로 JVM 내부 구조를 재구성합니다. JVM의 버전마다 메모리 레이아웃이 다르기 때문에 -F모드 jmap는 대상 Java 프로세스와 동일한 JDK에서 온 경우에만 작동합니다 .

  4. 이 도구는 자체적으로 힙 덤프를 만든 다음 대상 프로세스를 다시 시작합니다.

찬성.

  • 대상 JVM의 협력이 필요하지 않습니다. 매달린 프로세스에서도 사용할 수 있습니다.
  • ptraceOS 수준 권한이 충분할 때마다 작동합니다. 예를 들어 root다른 모든 사용자의 프로세스를 덤프 할 수 있습니다.

단점.

  • 큰 힙의 경우 매우 느립니다.
  • 도구와 대상 프로세스는 동일한 버전의 JDK에 있어야합니다.
  • 도구가 강제 모드로 부착되면 Safepoint가 보장되지 않습니다. jmap모든 특수한 경우를 처리하려고 시도 하지만 때때로 대상 JVM이 일관된 상태가 아닌 경우가 발생할 수 있습니다.

노트

강제 모드에서 힙 덤프를 가져 오는 더 빠른 방법이 있습니다. 먼저를 사용하여 코어 덤프를 gcore만든 다음 jmap생성 된 코어 파일에서 실행 합니다. 관련 질문을 참조하십시오 .


84

방금 jmap (그리고 힙 덤프를 생성하는 데 사용할 때 jvisualvm)이 jmap을 실행하는 사용자가 덤프를 시도하는 프로세스를 실행하는 동일한 사용자 여야한다는 것을 확인했습니다.

제 경우에는 힙 덤프를 원하는 jvm이 리눅스 사용자 "jboss"에 의해 실행되고 있습니다. 그래서 sudo jmap -dump:file.bin <pid>"Unable to open socket :"을보고하는 곳 에서 다음을 사용하여 힙 덤프를 얻을 수있었습니다.

sudo -u jboss jmap -dump:file.bin <pid>

sudo에서 jmap으로 매개 변수를 전달할 때-를 이스케이프해야하므로 \ -dump : file.bin <pid>이어야한다고 생각합니다.
adam

이거 야! jmap 및 jcmd에도 sudo가 필요합니다.
xtian

와우 .. 이거 실제로 효과가 있었어요. 이것은 허용 대답해야한다
더 그랜드 라오

3

ben_wing이 말한 것처럼 다음과 같이 실행할 수 있습니다.

sudo -u jboss-as jmap -dump:file.bin <pid>

(제 경우 사용자는 jboss-as이지만 귀하는 jboss또는 다른 사용자가 될 수 있습니다 .)

그러나 다른 명령으로 암호를 묻지 않고 실행할 수는 있었지만 암호 ( [sudo] password for ec2-user:) 를 요구 했기 때문에 충분하지 않았습니다 sudo.

여기 에서 해결책을 찾았고 sudo먼저 다른 것을 추가해야했습니다 .

sudo sudo -u jboss-as jmap -dump:file.bin <pid>

과 같은 다른 명령 jcmdjinfo도 함께 작동합니다 .


sudo배가 내 하루를 구합니다!
Sher10ck

[root@v5 ~]# sudo sudo -u es jmap -dump:file=tmp.bin 26283 오류를 켭니다 sudo: jmap: command not found. 이미 .bash_profile에 Java 경로를 구성했습니다. 어떻게해야합니까?
roamer

@roamer 아마도 그것은 es사용자 로 실행할 때 .bash_profile적용되지 않기 때문일 수 있습니다 (bash 프로필이 사용자와 관련이 있기 때문에 가정합니다). 더 전역적인 방식으로 Java 경로를 포함하거나 명령에 Java 경로를 지정하는 것이 좋습니다 sudo sudo -u es PATH="$PATH:/java/path" jmap -dump:file=tmp.bin 26283( 예 : ( /java/pathjava 경로는 어디에 있는지, 그 안에 있는지 확인하십시오jmap )).
Lucas Basquerotto

/home/es/.bash_profile에 Java 경로를 구성하고 es 사용자로 로그인 할 때 jmap을 사용할 수 있습니다. 이 cmd가 sudo sudo -u es /usr/java/jdk1.8.0_181-cloudera/bin/jmap -dump:file=tmp.bin 26283작동합니다. 감사합니다.
roamer

2

애플리케이션이 systemd 서비스로 실행중인 경우 /usr/lib/systemd/system/서비스 이름 아래 에 이름이 지정된 서비스 파일을 열어야합니다 . 그런 다음 privateTmp 속성이 true 인지 확인합니다 .

true 인 경우 false로 변경하고 다음과 같이 명령으로 서비스를 새로 고 systemctl daemon-reload systemctl restart [servicename] 칩니다. 다시 시작하기 전에 jmap / jcmd를 실행하려면 서비스 파일에서 execStop 스크립트를 사용할 수 있습니다. 명령을 입력하고 실행하십시오.systemctl stop [service name]


/usr/lib/systemd/system/elasticsearch.service를 업데이트하고 privateTmp를 false로 설정하기 전에 다음 오류가 발생했습니다. 소켓 파일을 열 수 없음 : 대상 프로세스가 응답하지 않거나 HotSpot VM이로드되지 않음-jmap을 다음과 같이 실행 중임에도 불구하고 elasticsearch 사용자
imdibiji
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.