Java 远程JVM中对象的JDI镜像的生命周期
我一直在编写一个Java客户机,它用于在远程JVM中创建和修改对象(通过连接到远程JVM中运行的基于代理的服务器)。我的项目的一个要求是,我不能挂起远程JVM中的所有线程,这意味着我创建的对象在我能够在JVM中访问之前可能会受到垃圾收集的影响 在某些情况下,我在远程JVM中创建对象,但它们被随机垃圾收集。例如,如果我通过在远程JVM中创建一个数组,有时在我可以从远程JVM中的另一个可访问对象“可访问”之前,该数组将被垃圾收集 (例如,如果我试图将新数组存储到现有可访问对象的字段中,对的调用可能会随机抛出。): 从理论上讲,Java 远程JVM中对象的JDI镜像的生命周期,java,garbage-collection,jvm,jdi,jdwp,Java,Garbage Collection,Jvm,Jdi,Jdwp,我一直在编写一个Java客户机,它用于在远程JVM中创建和修改对象(通过连接到远程JVM中运行的基于代理的服务器)。我的项目的一个要求是,我不能挂起远程JVM中的所有线程,这意味着我创建的对象在我能够在JVM中访问之前可能会受到垃圾收集的影响 在某些情况下,我在远程JVM中创建对象,但它们被随机垃圾收集。例如,如果我通过在远程JVM中创建一个数组,有时在我可以从远程JVM中的另一个可访问对象“可访问”之前,该数组将被垃圾收集 (例如,如果我试图将新数组存储到现有可访问对象的字段中,对的调用可能会
ObjectReference
的镜像甚至可能在我能够调用之前被垃圾收集(这是出于其他原因我不想采取的步骤)
所以我的问题是,JDI值
s上是否有记录在案的寿命保证
- 在远程JVM中,原语值的镜像是否免于GC?(有人假设是这样,但是
方法文档中没有一个能说明任何问题。).mirror*()
- a是否免于GC?(人们可能会认为不是,但JavaDoc似乎是沉默的。)
- 我假设任何其他
都可以在任何时候进行GC,除非您以前在它上面禁用了GCObjectReference
提前感谢您的帮助 尽管我找不到任何文档能够准确地从我想要的角度来解决问题,但是结合查看上的
com.sun.tools.jdi
包的源代码,我得出以下结论:
字符串的引用,都可以随时进行垃圾收集
LongValueImpl
的一个新实例,并返回:
public LongValue mirrorOf(long value) {
validateVM();
return new LongValueImpl(this,value);
}
您可以看到,无论是LongValueImpl
的构造函数,还是它的任何超类的构造函数,一直到MirrorImpl
都不会通过JDWP传输传输数据,从而改变服务器JVM的状态
与#2形成对比。中的起点是可以随时对任何ObjectReference
的镜像对象进行垃圾收集:
ObjectReference
上的任何方法,或直接或间接采用
ObjectReference
作为参数,如果
镜像对象已被垃圾回收
这一点得到了源代码的证实,它与服务器中的JDWP代理通信。这只是确认,与任何ObjectReference
aStringReference
一样,以这种方式创建的a在任何时候都容易受到GC的影响,包括立即
public StringReference mirrorOf(String value) {
validateVM();
try {
return (StringReference)JDWP.VirtualMachine.CreateString.
process(vm, value).stringObject;
} catch (JDWPException exc) {
throw exc.toJDIException();
}
}
因此,据我所知,如果您有任何ObjectReference
,您需要在捕获ObjectCollectedException
的循环中保护与远程JVM中镜像对象交互的所有尝试,除非远程JVM中的所有线程都挂起。例如,如果您的JDI客户机中有一个方法在远程JVM中创建一个字符串
,并返回一个不可垃圾回收的引用,那么您可以按照以下方式执行操作:
StringReference safeStringRef(VirtualMachine vm, String string) {
ObjectCollectedException lastCause = null;
for (int numTries = 0; numTries < SANE_TRY_LIMIT; ++numTries) {
StringReference stringRef = vm.mirrorOf(string);
try {
stringRef.disableCollection();
return stringRef;
} catch (ObjectCollectedException e) {
lastCause = e;
}
}
throw new RuntimeException("Can't create safe string reference", lastCause);
}
StringReference-safeStringRef(虚拟机虚拟机,字符串){
ObjectCollectedException lastCause=null;
对于(整数位数=0;整数位数
一件可能对您有用的事情是,它向调试过的JVM发出信号,表示永远不要收集该对象。谢谢,这确实帮助了我!:)
StringReference safeStringRef(VirtualMachine vm, String string) {
ObjectCollectedException lastCause = null;
for (int numTries = 0; numTries < SANE_TRY_LIMIT; ++numTries) {
StringReference stringRef = vm.mirrorOf(string);
try {
stringRef.disableCollection();
return stringRef;
} catch (ObjectCollectedException e) {
lastCause = e;
}
}
throw new RuntimeException("Can't create safe string reference", lastCause);
}