RFR: 8256811: Delayed/missed jdwp class unloading events [v15]

Chris Plummer cjplummer at openjdk.org
Tue Jul 12 03:44:48 UTC 2022


On Tue, 12 Jul 2022 01:44:28 GMT, Zhengyu Gu <zgu at openjdk.org> wrote:

>> Currently, jdi only check and process class unloading event when it detects a new GC cycle.
>> 
>> After [JDK-8212879](https://bugs.openjdk.org/browse/JDK-8212879), posting class events can overlap with GC finish event, that results, sometimes, it only captures partial or even empty unloaded class list. The pending list usually can be flushed out at next GC cycle. But for the classes unloaded during the last GC cycle, the class unloading events may lost forever.
>> 
>> This patch checks and processes class unloading events unconditionally, suggested by @kbarrett, the last pending unloaded class list can be flushed by other events, such as `VM_DEATH`.
>> 
>> It also performs `commonRef_compact()` only when there are classes unloaded.
>> 
>> New test failed about 20% without patch, none with patch.
>> 
>> **Update**
>> There are significant changes from early patch. 
>> 
>> The new approach:
>> No longer removing dead objects and post events on VM thread. I believe it was implemented this way to workaround the following issues:
>> - JDI event handler uses JVMTI raw monitor, it requires thread in `_in_native` state
>> - The thread can not hold lock, which is needed to protect `JvmtiTagMap` while walking, when transition to `_in_native` state
>> 
>> The new solution breaks up into two steps:
>> - Collect all dead object tags with lock
>> - Transition to `_in_native` state and post object free events in one batch
>> 
>> This way, JDI event handler can process object free events upon arrivals without delay.
>> 
>> **Update 2**
>> There is a comment for ` JvmtiTagMap::check_hashmap()` that states `ObjectFree` events are posted before heap walks.
>> 
>> // This checks for posting and rehashing before operations that
>> // this tagmap table.  The calls from a JavaThread only rehash, posting is
>> // only done before heap walks.
>> void JvmtiTagMap::check_hashmap(bool post_events) {
>> 
>> Now, the events are actually posted after heap walks, but I don't think it makes any material material difference. 
>> Even the events are posted earlier in old code, but they are only processed after next GC cycle.
>
> Zhengyu Gu has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Rename test

CASE #4:
Allocating objects...
Start thread and making garbage collection
thread4 started.
- ap04t001.cpp, 326: Calling IterateOverInstancesOfClass...
- ap04t001.cpp, 254:   run: ForceGarbageCollection
- ap04t001.cpp, 333: IterateOverInstancesOfClass finished.
- ap04t001.cpp, 335: Iterations count: 100000
- ap04t001.cpp, 336: Events count: 0
- ap04t001.cpp, 339: Errors detected: 0
- ap04t001.cpp, 228:   event: GarbageCollectionStart
- ap04t001.cpp, 234:   event: GarbageCollectionFinish
thread4 finished.
All objects collected
Wait for thread to finish
CASE #4 finished.

- ap04t001.cpp, 431: Let debugee to finish
The following fake exception stacktrace is for failure analysis. 
nsk.share.Fake_Exception_for_RULE_Creation: (ap04t001.cpp:75) jvmti->RawMonitorExit(counterMonitor_ptr)
	at nsk_lvcomplain(nsk_tools.cpp:172)
# ERROR: ap04t001.cpp, 75: jvmti->RawMonitorExit(counterMonitor_ptr)
#   jvmti error: code=50, name=JVMTI_ERROR_INVALID_MONITOR
# ERROR: ap04t001.cpp, 69: jvmti->RawMonitorEnter(counterMonitor_ptr)
#   jvmti error: code=50, name=JVMTI_ERROR_INVALID_MONITOR


And these two ERRORs get repeated a large number of times. I think this is likely a test bug. It probably is freeing the monitor before heap iterating is complete. I'm just not sure how it relates to your JVMTI changes.

-------------

PR: https://git.openjdk.org/jdk/pull/9168


More information about the hotspot-runtime-dev mailing list