Lock-based vs lock-free MethodCounters initialization
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Mon May 12 15:09:28 UTC 2014
On 5/12/14 5:09 PM, Mikael Gerdin wrote:
>> 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;
> }
MethodCounters have fixed size, but it's too small -
MethodCounters::size() reports 4 words for Tiered in 64-bit VM and
TreeChunk::min_size() is 12 words.
> 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.
I'll choose lock-based solution then. Thanks for the info.
Best regards,
Vladimir Ivanov
>
> /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