# HG changeset patch # User zgu # Date 1352477046 18000 # Node ID ed8b1e39ff4fab0ff5453337cc3c8799ee3c56a2 # Parent 18fb7da425345267c14c6dc1c52274e2018546d0 8002273: NMT to report JNI memory leaks when -Xcheck:jni is on Summary: Allows NMT to report that JNI thread failed to detach from JVM before exiting, which leaks the JavaThread object when check:jni option is on. Reviewed-by: acorn, dholmes, coleenp, ctornqvi diff -r 18fb7da42534 -r ed8b1e39ff4f src/share/vm/services/memSnapshot.cpp --- a/src/share/vm/services/memSnapshot.cpp Tue Nov 06 15:09:37 2012 -0500 +++ b/src/share/vm/services/memSnapshot.cpp Fri Nov 09 11:04:06 2012 -0500 @@ -123,20 +123,31 @@ // in different types. bool VMMemPointerIterator::add_reserved_region(MemPointerRecord* rec) { assert(rec->is_allocation_record(), "Sanity check"); - VMMemRegion* cur = (VMMemRegion*)current(); + VMMemRegion* reserved_region = (VMMemRegion*)current(); // we don't have anything yet - if (cur == NULL) { + if (reserved_region == NULL) { return insert_record(rec); } - assert(cur->is_reserved_region(), "Sanity check"); + assert(reserved_region->is_reserved_region(), "Sanity check"); // duplicated records - if (cur->is_same_region(rec)) { + if (reserved_region->is_same_region(rec)) { return true; } - assert(cur->base() > rec->addr(), "Just check: locate()"); - assert(!cur->overlaps_region(rec), "overlapping reserved regions"); + // Overlapping stack regions indicate that a JNI thread failed to + // detach from the VM before exiting. This leaks the JavaThread object. + if (CheckJNICalls) { + guarantee(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) != mtThreadStack || + !reserved_region->overlaps_region(rec), + "Attached JNI thread exited without being detached"); + } + // otherwise, we should not have overlapping reserved regions + assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack || + reserved_region->base() > rec->addr(), "Just check: locate()"); + assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack || + !reserved_region->overlaps_region(rec), "overlapping reserved regions"); + return insert_record(rec); }