Lock-based vs lock-free MethodCounters initialization
Mikael Gerdin
mikael.gerdin at oracle.com
Mon May 12 13:09:04 UTC 2014
Hi Vladimir,
On Monday 12 May 2014 15.19.04 Vladimir Ivanov wrote:
> Hi,
>
> There's a possible memory leak when allocating MethodCounters
> concurrently [1], because there's no coordination between concurrent
> counters initialization actions. In constrast with MethodCounters,
> MethodData allocation is guarded by MethodData lock.
>
> I'm thinking about proper fix and considering 2 options: lock-based
> (reuse MethodData_lock or introduce MethodCounters_lock) and lock-free
> (do a CAS on _method_counters field) [3].
>
> The problem with lock-based approach is that there's a possible deadlock
> with pending list lock (see JDK-6988439 [4] for details), so I need to
> check whether PLL is held and abort initialization in case it is
> (similar to what Method::build_interpreter_method_data does before
> acquiring the lock [2]).
>
> Lock-free solution doesn't suffer from deadlocks, but it can increase
> Metaspace fragmentation due to failed CAS updates and subsequent
> deallocations.
>
> I'm in favor of lock-free solution, but not sure about how serious
> fragmentation issue is in NPG world. What do you think?
1. Are MethodCounters objects large enough to fit on the per-metaspace block
free list? See:
MetaWord* BlockFreelist::get_block(size_t word_size) {
(...)
if (word_size < TreeChunk<Metablock, FreeList<Metablock> >::min_size()) {
// Dark matter. Too small for dictionary.
return NULL;
}
2. If the above is true, are all MethodCounters the same size? I know how you
guys love your variable-sized objects :)
If this is not true then we could encounter some severe fragmentation in
Metaspace. There are already several issues with fragmentation and waste and I
would prefer if we could avoid adding to the problem.
/Mikael
>
> Thanks!
>
> Best regards,
> Vladimir Ivanov
>
> [1]
> http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/tip/src/share/vm/oops/m
> ethod.cpp#l384
>
> MethodCounters* Method::build_method_counters(Method* m, TRAPS) {
> methodHandle mh(m);
> ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
> MethodCounters* counters = MethodCounters::allocate(loader_data,
> CHECK_NULL);
> if (mh->method_counters() == NULL) {
> mh->set_method_counters(counters);
> } else {
> MetadataFactory::free_metadata(loader_data, counters);
> }
> return mh->method_counters();
> }
>
> [2]
> http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/tip/src/share/vm/oops/m
> ethod.cpp#l360
>
> void Method::build_interpreter_method_data(methodHandle method, TRAPS) {
> // Do not profile method if current thread holds the pending list lock,
> // which avoids deadlock for acquiring the MethodData_lock.
> if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
> return;
> }
>
> // Grab a lock here to prevent multiple
> // MethodData*s from being created.
> MutexLocker ml(MethodData_lock, THREAD);
> if (method->method_data() == NULL) {
> ClassLoaderData* loader_data =
> method->method_holder()->class_loader_data();
> MethodData* method_data = MethodData::allocate(loader_data, method,
> CHECK);
> method->set_method_data(method_data);
> if (PrintMethodData && (Verbose || WizardMode)) {
> ResourceMark rm(THREAD);
> tty->print("build_interpreter_method_data for ");
> method->print_name(tty);
> tty->cr();
> // At the end of the run, the MDO, full of data, will be dumped.
> }
> }
> }
>
> [3] Possible lock-free solution:
> MethodCounters* Method::build_method_counters(Method* m, TRAPS) {
> methodHandle mh(m);
> if (mh->method_counters() != NULL) return mh->method_counters();
> ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
> MethodCounters* counters = MethodCounters::allocate(loader_data,
> CHECK_NULL);
> MethodCounters* old = (MethodCounters*)Atomic::cmpxchg_ptr(counters,
> &_method_counters, NULL);
> if (old != NULL) {
> MetadataFactory::free_metadata(loader_data, counters);
> }
> return mh->method_counters();
> }
>
> [4] https://bugs.openjdk.java.net/browse/JDK-6988439
More information about the hotspot-dev
mailing list