RFR: 8185525: [Event Request] Add Tracing event for DictionarySizes
gerard ziemski
gerard.ziemski at oracle.com
Fri Apr 5 15:42:27 UTC 2019
Thank you Erik for more suggestions.
I have implemented them, which you can find here
http://cr.openjdk.java.net/~gziemski/8185525_rev3
I will start Mach5 tier1-6 test to test the changes shortly
On 4/4/19 4:11 PM, Erik Gahlin wrote:
> Thanks for fixing.
>
> A quick comments about the test.
>
> I think it can be simplified by using some of the test library
> functionality, i.e
>
> public static void main(String[] args) throws Throwable {
> try (Recording recording = new Recording()) {
> recording.enable(EventNames.SymbolTableStatistics);
> recording.enable(EventNames.StringTableStatistics);
> recording.enable(EventNames.PlaceholderTableStatistics);
> recording.enable(EventNames.LoaderConstraintsTableStatistics);
> recording.enable(EventNames.ProtectionDomainCacheTableStatistics);
> recording.start();
> recording.stop();
>
> List<RecordedEvent> events = Events.fromRecording(recording);
> verifyTable(events, EventNames.SymbolTableStatistics);
> verifyTable(events, EventNames.StringTableStatistics);
> verifyTable(events, EventNames.PlaceholderTableStatistics);
> verifyTable(events, EventNames.LoaderConstraintsTableStatistics);
> verifyTable(events,
> EventNames.ProtectionDomainCacheTableStatistics);
> }
> }
>
> private static void verifyTable(List<RecordedEvent> allEvents,
> String eventName) throws Exception {
> List<RecordedEvent> eventsForTable = allEvents.stream()
> .filter(e ->
> e.getEventType().getName().equals(eventName))
> .collect(Collectors.toList());
> if (eventsForTable.isEmpty()) {
> throw new Exception("No events for " + eventName);
> }
> for (RecordedEvent event : eventsForTable) {
> Events.assertField(event, "bucketCount").atLeast(0L);
> long entryCount = Events.assertField(event,
> "entryCount").atLeast(0L).getValue();
> Events.assertField(event, "totalFootprint").atLeast(0L);
> long averageBucketCount = Events.assertField(event,
> "averageBucketCount").atLeast(0L).getValue();
> Events.assertField(event,
> "maximumBucketCount").atLeast(averageBucketCount);
> Events.assertField(event, "bucketCountVariance").atLeast(0.0f);
> Events.assertField(event,
> "bucketCountStandardDeviation").atLeast(0.0f);
> float insertionRate = Events.assertField(event,
> "insertionRate").atLeast(0.0f).getValue();
> float removalRate = Events.assertField(event,
> "removalRate").atLeast(0.0f).getValue();
> if ((insertionRate > 0.0f) && (insertionRate > removalRate)) {
> Asserts.assertGreaterThan(entryCount, 0L, "Entries marked as
> added, but no entries found for " + eventName);
> }
> }
> }
>
> - It's nice to have the main method on top so you can easily see what
> the test is supposed to do.
> - Changed (some) field names that used the previous naming style.
> - Reduced the number of methods to make it easier to read
> - Reduced number of calls to Events.fromRecording(...) as will
> repeatedly dump a file to disk.
> - Used Events.assertField() which will provide better error message if
> an assertion fails,
> - Used EventType::getName instead of event.toString() contains
> - Added sanity checks for standard deviation and variance fields
> - Wrapped Recording creation in try-with-resource to avoid warning
> about resource leak
> - Removed threshold as the events are periodic and don't use a threshold
> - Removed "Thread.sleep"
> - The test now relies on events having period "everyChunk" which means
> at least two events per recording are guaranteed
>
> Could you explain how the string table test work, and why it needs
> special handling?
Some tables might have zero entries, so I just wanted to be clear that
for StringTable (which will always have some entries) we do something
that will make it grow. I was planning on doing more elaborate tests,
but I don't think it's necessary.
>
> I also missed changes to the file EventNames.java
>
> (I haven't actually tried the code, but you get the idea)
I fixed it up just a bit, and it works nice, thanks!
>
> Thanks
> Erik
>
>> Thank you Erik for clarifications.
>>
>> I have implemented all your suggestions, which you can find here
>> http://cr.openjdk.java.net/~gziemski/8185525_rev2
>>
>> I started Mach5 tier1-6 test to test the changes ...
>>
>>
>> cheers
>>
>> On 4/4/19 1:16 PM, Erik Gahlin wrote:
>>> On 2019-04-04 17:39, gerard ziemski wrote:
>>>> hi Erik,
>>>>
>>>>
>>>> On 4/3/19 12:44 PM, Erik Gahlin wrote:
>>>>> Hi Gerard,
>>>>>
>>>>> Here are some comments about the metadata (to make it consistent
>>>>> with other events).
>>>>>
>>>>> The events should not be in the "Java Application" category since
>>>>> they are JVM events. You could perhaps put them in "Java Virtual
>>>>> Machine, Runtime, Tables". Some comments about the names and
>>>>> labels of fields.
>>>>>
>>>>> - Label: Number of buckets => Bucket Count
>>>>> - Label: Number of entries => Entry Count
>>>>> - Label: Total footprint => Total Footprint
>>>>>
>>>>> Could you remove descriptions that are exactly the same as the label.
>>>>>
>>>>> - Label: Maximum bucket size => Maximum Bucket Size
>>>>> - Label: Average bucket size => Average Bucket Size
>>>>> - Label: Variance of bucket size => Bucket Size Variance
>>>>> - Name: stdDevOfBucketSize => bucketSizeStandardDeviation
>>>>> - Label: Standard deviation of bucket size => Bucket Size Standard
>>>>> Deviation"
>>>>>
>>>>> Instead of using the word "size", it may make more sense to use
>>>>> the word "count" here as well, i.e "Average Bucket Count", or
>>>>> maybe I'm missing something? Is there a difference?
>>>>>
>>>>> I wonder how useful standard deviation and variance is? If support
>>>>> engineers are looking at a recording, or JMC adds a rule for the
>>>>> events, what would a good or bad value be? Is it possible to use
>>>>> the information for troubleshooting?
>>>>
>>>> While I'm working on all the above changes you suggested, we can
>>>> discuss the standard devation and variance.
>>>>
>>>> I added them because they are part of the jcmd "VM.symboltable
>>>> -verbose" command, so we are consistent.
>>> OK
>>>>
>>>> Now, regarding how useful they are, I always understood them as a
>>>> sign of imbalanced table distribution, and without a proper
>>>> histogram, this is the best description of the histogram shape. In
>>>> reality, however, I think that if they identify an issue, then we
>>>> might have a very curious distribution (some sort of hash table
>>>> attack), or we have an issue with our hash function for the
>>>> particular usage case.
>>>>
>>>> Still, I'd personally elect to keep them.
>>>>
>>>> Let me ask you a different question though, Is it expensive to have
>>>> 2 doubles as part of an event (5 events per second)?
>>> Doubles can't be compressed so each value will take 8 bytes. I don't
>>> think the precision of a double is needed, so you could change it
>>> into a float and save a few bytes.
>>>
>>> Most user will not care about JVM internals and a lower rate than
>>> once per second is probably sufficient for support engineers to spot
>>> that something is wrong.
>>>
>>> The Thread Context Switch Rate event is emitted once every ten
>>> seconds. I think the same rate could be used here.
>>>
>>>> And if so, is there currently (or planned) granularity for
>>>> controlling not just which events to record, but also which
>>>> attributes?
>>>>
>>> No.
>>>
>>> If overhead becomes an issues, it's usually better to emit all the
>>> information, but at a lower rate. That way, users can find out that
>>> the information exists, and increase the rate if a higher resolution
>>> is needed to solve their specific issue.
>>>
>>>>>
>>>>> - Name: addRate => insertionRate
>>>>> - Label: Rate of addition => Insertation Rate
>>>>> - Name: removeRate => removalRate
>>>>> - Label: Rate of removal => Removal Rate
>>>>
>>>> Will do.
>>>>
>>>>>
>>>>> I'm missing unit tests for the events. Could you please add in
>>>>> /test/jdk/jdk/jfr/event/runtime. They can be sanity tests. i.e the
>>>>> average not exceeding max, no negative values etc.
>>>>
>>>> Working on it, do we need separate test per each event (table), or
>>>> just one table will suffice (ex. StringTable)?
>>> They are kind of similar, so I think one test file is sufficient,
>>> but we should sanity check data for all events.
>>>
>>> Thanks
>>> Erik
>>>
>>>>
>>>> Thank you for the feedback!
>>>>
>>>>
>>>> cheers
>>>>>
>>>>> Thanks!
>>>>> Erik
>>>>>
>>>>>> Hi all,
>>>>>>
>>>>>> Please review this feature, which adds tracing events for the
>>>>>> internal hash tables.
>>>>>>
>>>>>> The following attributes are implemented:
>>>>>>
>>>>>> <Field type="ulong" name="numberOfBuckets" label="Number of
>>>>>> buckets" description="Number of buckets" />
>>>>>> <Field type="ulong" name="numberOfEntries" label="Number of
>>>>>> entries" description="Number of all entries" />
>>>>>> <Field type="ulong" contentType="bytes" name="totalFootprint"
>>>>>> label="Total footprint" description="Total memory footprint (the
>>>>>> table itself plus all of the entries)" />
>>>>>> <Field type="ulong" name="maximumBucketSize" label="Maximum
>>>>>> bucket size" description="The maximum bucket length (entries in a
>>>>>> single bucket)" />
>>>>>> <Field type="double" name="averageBucketSize" label="Average
>>>>>> bucket size" description="The average bucket length (entries in a
>>>>>> bucket)" /> <Field type="double" name="varianceOfBucketSize"
>>>>>> label="Variance of bucket sizes" description="How far bucket
>>>>>> lengths are spread out from their average value" />
>>>>>> <Field type="double" name="stdDevOfBucketSize" label="Standard
>>>>>> deviation of bucket sizes" description="How far bucket lengths
>>>>>> are spread out from their mean (expected) value" />
>>>>>> <Field type="double" name="addRate" label="Rate of addition"
>>>>>> description="How many items were added since last event (per
>>>>>> second)" />
>>>>>> <Field type="double" name="removeRate" label="Rate of removal"
>>>>>> description="How many items were removed since last event (per
>>>>>> second)" />
>>>>>>
>>>>>> This event was implemented for the following system tables:
>>>>>>
>>>>>> SymbolTable
>>>>>> StringTable
>>>>>> Placeholder Table
>>>>>> LoaderConstraints Table
>>>>>> ProtectionDomainCache Table
>>>>>>
>>>>>> Webrev: http://cr.openjdk.java.net/~gziemski/8185525_rev1/
>>>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8185525
>>>>>> Testing: Mach5 tier1,2,3 (another Mach5 tier1,2,3,4,5,6,7 in
>>>>>> progress…)
>>>>>>
>>>>>>
>>>>>> Cheers
>
>
More information about the jmc-dev
mailing list