invokeMethod's result gced immediately

Chris Plummer chris.plummer at oracle.com
Thu Mar 12 16:53:49 UTC 2020


Hi Egor,

This stems from the JDWP spec. If you look at the 
ObjectReference.DisableCollection command:

https://docs.oracle.com/javase/10/docs/specs/jdwp/jdwp-protocol.html#JDWP_ObjectReference_DisableCollection

"By default all objects in back-end replies may be collected at any time 
the target VM is running. A call to this command guarantees that the 
object will not be collected."

Yes, it can be annoying that by default collection is not already 
disabled on any returned ObjectReference. We've had some tests with 
intermittent failures because they were buggy in this regard. I think 
there are two reasons it is done this way, both mentioned in the above 
JDWP section. The first is:

"Note that while the target VM is suspended, no garbage collection will 
occur because all threads are suspended. The typical examination of 
variables, fields, and arrays during the suspension is safe without 
explicitly disabling garbage collection."

So it's quite common not to need to DisableCollection on the object. 
Second is:

"This method should be used sparingly, as it alters the pattern of 
garbage collection in the target VM and, consequently, may result in 
application behavior under the debugger that differs from its 
non-debugged behavior."

So it looks like there's good reason to limit using DisableCollection.

It's a bit unclear to me how your foo().boo().zoo() example is 
implemented. Are you under a SUSPEND_ALL when you do the invoke? If so, 
all threads should still be suspended after the invoke completes, so you 
should be able to call DisableCollection without having to worry about 
it failing due to the object already being collected. This should set 
you up to use the objectref in the next invoke in the chain, once again 
without worry about having to retry due to collection.

cheers,

Chris

On 3/12/20 3:12 AM, Egor Ushakov wrote:
> Hi all,
>
> it seems that the result of the invokeMethod could be gced 
> immediately, which is quite strange.
> Currently we have to do:
> invoke + disableCollection
> new(Array)Instance + disableCollection
> (String)mirrorOf + disableCollection
> in a loop until succeeded, to allow something like foo().boo().zoo() 
> to evaluate successfully.
> Is there a way to automatically disable collection for newly created 
> objects from jdi?
> Maybe there's a bug about this?
>
> Thanks!
>



More information about the serviceability-dev mailing list