附加到由ProcessBuilder启动的JVM失败

时间:2017-10-24 16:38:20

标签: java jvm jmx

我正在比较大型系统中两个API实现的内存消耗。为了最大限度地减少系统其他部分的影响,我在ProcessBuilder启动的Process中运行该函数,使用JMX连接到新的Process,然后使用MemoryMXBean监视其内存消耗。这是我使用的代码:

val pb = new ProcessBuilder("/usr/bin/java",
  "-cp", "/home/ubuntu/main.jar",
  "-Xmx8G", "dataset.feature.EncMemoryUsageProcess",
  param1, param2)
val process = pb.start()
val pidfield = process.getClass.getDeclaredField("pid")
pidfield.setAccessible(true)
val pid = pidfield.get(process).toString

// Attach VM and obtain MemoryMXBean
val vm = VirtualMachine.attach(pid)
var connectorAddr = vm.getAgentProperties.getProperty("com.sun.management.jmxremote.localConnectorAddress")
if (connectorAddr == null) {
  val agent = vm.getSystemProperties.getProperty("java.home") + File.separator + "lib" + File.separator + "management-agent.jar"
  vm.loadAgent(agent)
  connectorAddr = vm.getAgentProperties.getProperty("com.sun.management.jmxremote.localConnectorAddress")
}
val serviceURL = new JMXServiceURL(connectorAddr)
val connector = JMXConnectorFactory.connect(serviceURL)
val mbsc = connector.getMBeanServerConnection
val mbeanName = new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME)
val memoryMXBean = JMX.newMXBeanProxy(mbsc, mbeanName, classOf[MemoryMXBean])

var maxMemory = 0l

while (process.isAlive) {
  Thread.sleep(200l);
  val memoryUsage = memoryMXBean.getHeapMemoryUsage.getUsed
  maxMemory = Math.max(memoryUsage, maxMemory);
}

return maxMemory

但是,代码抛出" com.sun.tools.attach.AttachNotSupportedException:无法打开套接字文件:目标进程未响应或HotSpot VM未加载"当我打电话给VirtualMachine.attach时。我用谷歌搜索并注意到这通常是由于没有生成pid文件引起的,一个常见原因是新的JVM不是由同一个用户创建的。但是,这似乎不是我的情况,因为我正在创建新的JVM作为子进程。

任何建议表示赞赏。谢谢!

更新

我注意到这个错误只发生在我启动多个进程时,如下所示(上面列出的代码是executeAndAttach):

for(int i = 0 ; i < 5;i++) {
    executeAndAttach(i, param);
}

我第一次执行executeAndAttach时,它会成功,但后续调用都会抛出异常。更奇怪的是,当我在LinuxVirtualMachine.findSocketFile()中调试时,异常被抛出的地方,错误消失了。

0 个答案:

没有答案