从另一个JVM加载JVM中的现有类对象

时间:2013-07-12 07:13:07

标签: java reflection jvm webserver

如何从另一个JVM加载JVM中的现有类对象?

我正在分析我服务器中罕见的情况。我的服务器中没有正确的日志来帮助我解决问题,我相信它可能是特定类对象(用户定义)的问题。

比如说以下是班级:

public class MyRequest 
{
  public byte[] getData()
  {
    return somdata;
  }
}

目前在我的服务器的JVM中,100个以上的类对象位于我的JVM内存中。我想知道是否有可能加载所有100个对象并访问其数据/方法(getData())。 我不想创建MyRequest类的新实例(我知道这很简单)。我想通过另一个Java进程从我的JVM加载现有对象。

P.S:我无法以任何理由杀死我的服务器。 P.S:我无法安装像visualvm等任何工具,而且更多的工具告诉我们对象类型,内存但不是确切的数据。

4 个答案:

答案 0 :(得分:2)

基本上,它不会起作用。

  1. 如果您无法附加调试器,则无法执行任何操作。

  2. 如果您可以附加调试器,您应该能够找到并查看这些实例,但是您无法让他们做一些他们没有做过的事情。 ; t旨在做。特别是,如果它们不是可序列化的,那么您将无法对它们进行序列化。

  3. 我认为您最好的选择是更改服务器代码以改进日志记录,然后使用调试器代理重新启动它......并等待问题重现。

    当然,如果你附加了调试器,则不需要将对象移动到另一个JVM。你可以直接看看他们的状态。


    然而,有一个问题。许多"非常罕见"场景实际上与线程,线程安全和时序问题有关。你可以做很多事情来观察这种错误的影响,这可能会改变程序的行为。


    <强>后续

      

    因此,如果我们知道该JVM的虚拟内存的起始地址......我们不能知道数据吗?假设所有对象都在JVM内存空间内。

    并不是那么简单:

    • Java堆上的对象位置无法预测。
    • 线程堆栈的位置不可预测。
    • 等等。
    理论上可能可以转储任何进程的内存,并重建JVM的执行状态,&#34; read&#34;对象的状态。但是,您需要专门的工具和/或JVM内部的大量知识才能做到这一点。我甚至不确定这些工具是否存在......

    简而言之,AFAIK是不切实际的。

答案 1 :(得分:1)

对象及其引用(别名)绑定到当前运行的JVM。没有可能在几个JVM之间共享它们。

如果要在两个JVM之间“共享”数据,则必须序列化此数据,这意味着将它们从JVM发送到另一个JVM。这还要求其实例应序列化的类实现接口Serializable。请注意,arrays automatically implement Serializable

您可以使用套接字,输出和输入流自行流式传输这些可序列化对象(这是非常省力的),或者您可以使用RMI来调用远程方法并只传输数据。在任何一种情况下,都会在另一个JVM中复制和重新构建所有对象。没有机会让他们分享。

对于应用程序服务器,通常只使用EJB调用RMI调用。但是你需要一个应用服务器;仅仅使用网络服务器是不够的。

答案 2 :(得分:1)

Load existing class objects in JVM from another JVM

不可能

答案 3 :(得分:0)

请注意,您可以告诉JVM将其状态(使用kill信号或类似信息)转储到磁盘,以便您可以使用post-Mortem工具来分析程序的状态。

关键词是“核心”和“hprof”,我自己还没有这样做。