RFR(M, v13): JDK-8059036 : Implement Diagnostic Commands for heap and finalizerinfo

Dmitry Samersoff dmitry.samersoff at oracle.com
Wed Jun 3 15:29:48 UTC 2015


Everyone,

Updated webrev:

http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.13

Changes to oop.inline.hpp is reverted and find_field used directly is
diagnostic command.

-Dmitry

On 2015-06-03 11:48, Dmitry Samersoff wrote:
> Everyone,
> 
> Updated webrev:
> 
> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.12
> 
> getFinalizerHistogram and FinalizerHistogramEntry moved to separate
> package-private class. Hotspot code changed accordingly.
> 
> getFinalizerHistogram updated to use Peter's code.
> 
> -Dmitry
> 
> 
> On 2015-06-03 09:06, Peter Levart wrote:
>> Hi Dmitry,
>>
>> On 06/02/2015 01:12 PM, Dmitry Samersoff wrote:
>>> Staffan,
>>>
>>>> Instead of hardcoding the field offsets, you can use
>>>> InstanceKlass::find_field and fieldDescriptor::offset to find the
>>>> offset at runtime.
>>> Done. Please, see
>>>
>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.11
>>
>> In the jdk part, now that you have a FinalizerHistogramEntry class, you
>> can simplify the code even further:
>>
>>
>>     private static final class FinalizerHistogramEntry {
>>         int instanceCount;
>>         final String className;
>>
>>         int getInstanceCount() {
>>             return instanceCount;
>>         }
>>
>>         FinalizerHistogramEntry(String className) {
>>             this.className = className;
>>         }
>>     }
>>
>>     static Object[] getFinalizerHistogram() {
>>         Map<String, FinalizerHistogramEntry> countMap = new HashMap<>();
>>         queue.forEach(r -> {
>>             Object referent = r.get();
>>             if (referent != null) {
>>                 countMap.computeIfAbsent(
>>                         referent.getClass().getName(),
>>                         FinalizerHistogramEntry::new).instanceCount++;
>>                 /* Clear stack slot containing this variable, to decrease
>>                    the chances of false retention with a conservative GC */
>>                 referent = null;
>>             }
>>         });
>>
>>         FinalizerHistogramEntry fhe[] = countMap.values()
>>                 .toArray(new FinalizerHistogramEntry[countMap.size()]);
>>         Arrays.sort(fhe,
>>                 Comparator.comparingInt(
>>                        
>> FinalizerHistogramEntry::getInstanceCount).reversed());
>>         return fhe;
>>     }
>>
>>
>> ... see, no copying loop required. Also notice the access modifier used
>> on the nested class and it's fields/method/constructor. This way the
>> class is private and fields can be accessed from getFinalizerHistogram
>> and lambda without compiler generating access bridges.
>>
>>
>> Regards, Peter
>>
>>>
>>> I put the function int get_filed_offset_by_name(Symbol*,Symbol*) to
>>> oop.inline.hpp leaving a room for further cleanup because I found couple
>>> of places in hotspot that implements mostly similar functionality.
>>>
>>> -Dmitry
>>>
>>> On 2015-06-01 10:18, Staffan Larsen wrote:
>>>> Dmitry,
>>>>
>>>> Instead of hardcoding the field offsets, you can use InstanceKlass::find_field and fieldDescriptor::offset to find the offset at runtime. 
>>>>
>>>> Thanks,
>>>> /Staffan
>>>>
>>>>> On 31 maj 2015, at 13:43, Dmitry Samersoff <dmitry.samersoff at oracle.com> wrote:
>>>>>
>>>>> Everyone,
>>>>>
>>>>> Please take a look at new version of the fix.
>>>>>
>>>>> http://cr.openjdk.java.net/~dsamersoff/JDK-8059036/webrev.10/
>>>>>
>>>>> Changes (to previous version) are in
>>>>> Finalizer.java and diagnosticCommand.cpp
>>>>>
>>>>> This version copy data from Map.Entry<> to array of
>>>>> FinalizerHistogramEntry instances then,
>>>>> VM prints content of this array.
>>>>>
>>>>> -Dmitry
>>>>>
>>>>>
>>>>> On 2015-05-28 21:06, Mandy Chung wrote:
>>>>>> On 05/28/2015 07:35 AM, Peter Levart wrote:
>>>>>>> Hi Mandy,
>>>>>>>
>>>>>>> On 05/27/2015 03:32 PM, Mandy Chung wrote:
>>>>>>>> Taking it further - is it simpler to return String[] of all
>>>>>>>> classnames including the duplicated ones and have the VM do the
>>>>>>>> count?  Are you concerned with the size of the String[]?
>>>>>>> Yes, the histogram is much smaller than the list of all instances.
>>>>>>> There can be millions of instances waiting in finalizer queue, but
>>>>>>> only a few distinct classes.
>>>>>> Do you happen to know what libraries are the major contributors to these
>>>>>> millions of finalizers?
>>>>>>
>>>>>> It has been strongly recommended to avoid finalizers (see Effective Java
>>>>>> Item 7).   I'm not surprised that existing code is still using
>>>>>> finalizers while we should really encourage them to migrate away from it.
>>>>>>
>>>>>>> What could be done in Java to simplify things in native code but still
>>>>>>> not format the output is to convert the array of Map.Entry(s) into an
>>>>>>> Object[] array of alternating {String, int[], String, int[], .... }
>>>>>>>
>>>>>>> Would this simplify native code for the price of a little extra work
>>>>>>> in Java? The sizes of old and new arrays are not big (# of distinct
>>>>>>> classes of finalizable objects in the queue).
>>>>>> I also prefer writing in Java and writing less native code (much
>>>>>> simplified).  It's an interface that we have to agree upon and keep it
>>>>>> simple.  Having the returned Object[] as alternate String and int[] is a
>>>>>> reasonable compromise.
>>>>>>
>>>>>> ReferenceQueue.java - you can move @SuppressWarning from the method to
>>>>>> just the field variable "rn"
>>>>>>     @SuppressWarnings("unchecked")
>>>>>>     Reference<? extends T> rn = r.next;
>>>>>>
>>>>>> Finalizer.java
>>>>>>     It's better to rename printFinalizationQueue as it inspects the
>>>>>> finalizer reference queue (maybe getFinalizerHistogram?).  Can you move
>>>>>> this method to the end of this class and add the comment saying that
>>>>>> this is invoked by VM for jcmd -finalizerinfo support and @return to
>>>>>> describe the returned content.  I also think you can remove
>>>>>> @SuppressWarnings for this method.
>>>>>>
>>>>>> Mandy
>>>>>
>>>>> -- 
>>>>> Dmitry Samersoff
>>>>> Oracle Java development team, Saint Petersburg, Russia
>>>>> * I would love to change the world, but they won't give me the sources.
>>>
>>
> 
> 


-- 
Dmitry Samersoff
Oracle Java development team, Saint Petersburg, Russia
* I would love to change the world, but they won't give me the sources.


More information about the hotspot-gc-dev mailing list