On Tue, 12 Jul 2022 01:44:28 GMT, Zhengyu Gu <z...@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