运行jmap获取无法打开套接字文件
我必须运行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 ... 
-  使用-F适合堆取出堆?
- 我等了20分钟,还没有完成。 任何想法为什么?
  jmap与jmap -F以及jstack与jstack -F使用完全不同的机制来与目标JVM进行通信。 
jmap / jstack
 当运行没有-F这些工具使用dynamic连接机制 。 这工作如下。 
- 
在连接到Java进程1234之前, jmap在目标进程的工作目录或/tmp创build一个.attach_pid1234的文件。
- 
然后 jmap将SIGQUIT发送到目标进程。 当JVM捕获信号并find.attach_pid1234,它启动AttachListener线程。
- 
AttachListener线程创buildUNIX域套接字/tmp/.java_pid1234以侦听来自外部工具的命令。
- 
出于安全原因,当接受来自 jmap的连接时,JVM将validation对等端的凭证是否等于JVM进程的euid和egid。 这就是为什么如果由不同的用户(即使是root)运行jmap也不行。
- 
jmap连接到套接字,并发送dumpheap命令。
- 
该命令由JVM的 AttachListener线程读取并执行。 所有的输出都被发送回套接字。 由于堆转储是由JVM直接进行的,操作非常快。 但是,JVM只能在安全点上执行此操作 。 如果无法达到安全点(例如进程挂起,没有响应或长时间的GC正在进行),则jmap将超时并失败。
我们来总结dynamic连接的优点和缺点。
优点。
- 堆转储和其他操作由JVM以最高速度协同运行。
-  您可以使用任何版本的jmap或jstack连接到任何其他版本的JVM。
缺点。
-  该工具应该由与目标JVM相同的用户( euid/egid)运行。
- 只能在实时和健康的JVM上使用。
-  如果目标JVM以-XX:+DisableAttachMechanism启动,将无法工作。
jmap -F / jstack -F
 当使用-F运行时,工具切换到以HotSpot可维护性代理程序为特色的特殊模式。 在这种模式下,目标进程被冻结; 这些工具通过OSdebugging工具读取它的内存,也就是Linux上的ptrace 。 
- 
jmap -F在目标JVM上调用PTRACE_ATTACH。 响应于SIGSTOP信号,目标进程被无条件地暂停。
- 
该工具使用 PTRACE_PEEKDATA读取JVM内存。ptrace只能读取一个字,所以读取目标进程的大堆时需要太多的调用。 这是非常非常缓慢的。
- 
该工具基于特定JVM版本的知识重buildJVM内部结构。 由于不同版本的JVM具有不同的内存布局,因此 -F模式仅在jmap来自与目标Java进程相同的JDK时才起作用。
- 
该工具自己创build堆转储,然后恢复目标进程。 
优点。
- 目标JVM不需要合作。 甚至可以在挂起的过程中使用。
-  只要操作系统级别的权限足够, ptrace可以工作。 例如root可以转储所有其他用户的进程。
缺点。
- 非常缓慢的大堆。
- 该工具和目标进程应该来自相同版本的JDK。
-  工具在强制模式下连接时,不保证安全点。 尽pipejmap尝试处理所有特殊情况,但有时可能发生目标JVM不处于一致状态。
注意
 在强制模式下有更快的堆转储方法。 首先,用gcore创build一个coredump,然后在生成的核心文件上运行jmap 。 看到相关的问题 。 
我刚刚发现,jmap(当使用它来生成堆转储时,大概是jvisualvm)强制运行jmap的用户必须是运行该进程的同一用户,试图转储。
 在我的情况下,jvm我想要一个堆转储正在运行的Linux用户“jboss”。 所以在哪里sudo jmap -dump:file.bin <pid>报告“无法打开套接字:”,我能够抓住我的堆转储使用: 
 sudo -u jboss jmap -dump:file.bin <pid> 
就像ben_wing说的那样,你可以运行:
 sudo -u jboss-as jmap -dump:file.bin <pid> 
  (在我的情况下,用户是jboss-as ,但是你可能是jboss或者其他的) 
 但这还不够,因为它向我提供了一个密码 ( [sudo] password for ec2-user: ,尽pipe我可以运行sudo而不用提示其他命令input密码。 
 我在这里find了解决scheme,我只需要首先添加另一个sudo : 
 sudo sudo -u jboss-as jmap -dump:file.bin <pid> 
 它也可以和其他命令一起使用,比如jcmd和jinfo 。