1

I was able to call ObjectHeap.iterateObjectsOfKlass (with the help of SA) to obtain all objects belonging to a certain class. The result is exactly what I have expected, but the performance is not.

It took me >800 seconds to get my result, during which the target VM is suspended. The target VM heap is about 2GB. I know iterateObjectsOfKlass will call iterateExact.

My question is: do these methods iterate/traverse the entire heap just to obtain objects for 1 class? I am disappointed since my expectation is that with a single class, the result should return within 10 seconds.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • 1
    Good question. However, it was not quite clear in the origin form (especially to people not familiar with the Serviceability Agent). – apangin Sep 13 '16 at 17:52
  • Sure, it has to scan the entire heap to find all objects of whatever kind. The type of filter has no influence on that fact. How did you expect it to work? – Holger Sep 14 '16 at 09:16
  • I wasn't expecting the entire heap to be scanned. I was thinking that since a class was specified, iterateObjectsOfKlass will be surgical in its object retrieval. - Matthias. Thanks @Holger – Matthias Ho Sep 14 '16 at 10:49
  • Well, but *how*? There is no link from a class to its existing instances. If there was, the links had to be updated in a thread-safe manner on every object creation, not to speak of object destruction, which is actually a no-op. That would be a dramatic performance degradation of the entire JVM, just for the sake of a potential invocation of that monitoring function… – Holger Sep 14 '16 at 11:00

1 Answers1

6

HotSpot Serviceability Agent is really powerful technology, but indeed very slow. I have explained how it works in this answer.

JVM has no means to quickly find all instances of the specific class. So, yes, it has to scan the entire heap. Moreover, in order to read memory of a foreign process, SA uses ptrace system call for every single word of data. That's why it is so slow.

You have several options to scan heap faster:

  1. Create a coredump of a foreign process and then run SA tool against the coredump. This is much faster than to read memory of a suspended process. See the related question.
  2. Inject a JVMTI agent into a running process using Dynamic Attach mechanism. The agent can scan heap of a local JVM using IterateOverInstancesOfClass function. This will be dramatically faster comparing to SA, because it will be just reading from within the same process without any syscalls or whatever. I believe it will take just a few seconds for a 2GB heap.
Community
  • 1
  • 1
apangin
  • 92,924
  • 10
  • 193
  • 247
  • are you aware of any existing tools currently using the JVMTI option here? I have built tools around coredump although it is not very pleasant to work with, having to copy SA_ALTROOT files around etc. – jasonk Dec 20 '19 at 22:33
  • 1
    @jasonk I don't. But I promote the idea that [creating your own tool](https://blogs.oracle.com/javamagazine/creating-your-own-debugging-tools) can be often faster than looking for an existing one that may or may not solve your particular problem well enough. – apangin Dec 20 '19 at 23:52
  • FWIW I have successful SA tooling against JDK8 which make it way faster, I am yet to open source any of it though. Might look to get it up for jdk17. – jasonk Mar 04 '21 at 23:48