如何从另一个JVM加载JVM中的现有类对象?
我正在分析我服务器中罕见的情况。我的服务器中没有正确的日志来帮助我解决问题,我相信它可能是特定类对象(用户定义)的问题。
比如说以下是班级:
public class MyRequest
{
public byte[] getData()
{
return somdata;
}
}
目前在我的服务器的JVM中,100个以上的类对象位于我的JVM内存中。我想知道是否有可能加载所有100个对象并访问其数据/方法(getData()
)。
我不想创建MyRequest类的新实例(我知道这很简单)。我想通过另一个Java进程从我的JVM加载现有对象。
P.S:我无法以任何理由杀死我的服务器。 P.S:我无法安装像visualvm等任何工具,而且更多的工具告诉我们对象类型,内存但不是确切的数据。
答案 0 :(得分:2)
基本上,它不会起作用。
如果您无法附加调试器,则无法执行任何操作。
如果您可以附加调试器,您应该能够找到并查看这些实例,但是您无法让他们做一些他们没有做过的事情。 ; t旨在做。特别是,如果它们不是可序列化的,那么您将无法对它们进行序列化。
我认为您最好的选择是更改服务器代码以改进日志记录,然后使用调试器代理重新启动它......并等待问题重现。
当然,如果你附加了调试器,则不需要将对象移动到另一个JVM。你可以直接看看他们的状态。
然而,有一个问题。许多"非常罕见"场景实际上与线程,线程安全和时序问题有关。你可以做很多事情来观察这种错误的影响,这可能会改变程序的行为。
<强>后续强>
因此,如果我们知道该JVM的虚拟内存的起始地址......我们不能知道数据吗?假设所有对象都在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”,我自己还没有这样做。