Call Counting not working with Java 11 and JDK classes

Questions about YourKit Java Profiler
Post Reply
cdietrich
Posts: 7
Joined: Wed Jul 08, 2020 12:55 pm

Call Counting not working with Java 11 and JDK classes

Post by cdietrich »

I am using Yourkit 2020.09 to profile with call_counting.
e.g. with this simple class

Code: Select all

	public static void main(String[] args) {
		Set<String> s = new HashSet<>();
		s.add("A");
		s.add("b");
		s.add("cccccc");
		for (int i=0; i< 10000000;i++) {
			Set<String> s2 = new HashSet<>(s);
		}
	}
when i profile this with call counting, then in the result jdk classes like
java.util.HashSet are missing and only inner classes for them are in the result

Code: Select all

"Name","Invocation Count"
"java.util.HashMap$EntrySpliterator.<init>(HashMap, int, int, int, int) HashMap.java","4"
"java.util.HashMap$EntrySpliterator.forEachRemaining(Consumer) HashMap.java","4"
"java.util.HashMap$HashMapSpliterator.<init>(HashMap, int, int, int, int) HashMap.java","31"
"java.util.HashMap$HashMapSpliterator.estimateSize() HashMap.java","24"
"java.util.HashMap$HashMapSpliterator.getFence() HashMap.java","67"
"java.util.HashMap$ValueSpliterator.<init>(HashMap, int, int, int, int) HashMap.java","27"
"java.util.HashMap$ValueSpliterator.forEachRemaining(Consumer) HashMap.java","22"
"java.util.HashMap$ValueSpliterator.tryAdvance(Consumer) HashMap.java","43"
"java.util.Hashtable$Enumerator.<init>(Hashtable, int, boolean) Hashtable.java","2"
"java.util.Hashtable$Enumerator.hasMoreElements() Hashtable.java","67"
"java.util.Hashtable$Enumerator.nextElement() Hashtable.java","65"

do i overlook some configuration?
cdietrich
Posts: 7
Joined: Wed Jul 08, 2020 12:55 pm

Re: Call Counting not working with Java 11 and JDK classes

Post by cdietrich »

same problem with 2021.3
Anton Katilin
Posts: 6172
Joined: Wed Aug 11, 2004 8:37 am

Re: Call Counting not working with Java 11 and JDK classes

Post by Anton Katilin »

Hi,

The problem is that the class java.util.HashMap is among a number of core classes which since Java 9 are loaded in a very early phase which does not allow the profiler to immediately apply bytecode instrumentation when the class loads, as it normally happens for other classes. To instrument such classes, the agent should retransform them at a later time point.

Retransforming all such classes is not feasible because JVM takes much more time to retransform an already loaded class than if the class is instrumented before being loaded.

Instead, the agent retransforms only a few selected classes which is needed for the built-in probes.

You can add the agent startup option "debug=bci" to enable bytecode instrumentation related messages in the log. Search for "skipped early class" to see all skipped classes and "Retransform early class" to see those few selected classes which the profiler agent retransforms.

As a workaround for your example, wrap the call(s) you want to measure in wrapping method(s), like this:

Code: Select all

  public static void main(final String[] args) {
    Set<String> s = new HashSet<>();
    s.add("A");
    s.add("b");
    s.add("cccccc");
    for (int i=0; i< 10000000;i++) {
      Set<String> s2 = newMap(s);
    }
  }

  @NotNull
  private static HashSet<String> newMap(final Set<String> s) {
    return new HashSet<>(s);
  }
You'll have all 10000000 invocations of newMap() recorded.
Post Reply