Search code examples
javaprimitivevisualvmoql

VisualVM OQL: how to search for primitive float values rather than actual Float instances?


I am wondering how one can search for all primitive float values that match a certain number.

When doing something like:

select n from java.lang.Float n where n.value == 1.00

Only the Float class instances are being found. The application I am exploring is using different wrappers than just Float (eg. Vectors) that use primitive float values as fields for which I need to search.

How would I accomplish this?

The following returns a "float is not found error":

select n from float n where n.value == 1.00

Solution

  • A primitive value exists only as a field in the structure it's a part of (or directly on the stack). Because it isn't an object, it can't be referenced. Try something like the following:

    select v from Vector v where v.x == 1.0 || v.y == 1.0 || v.z == 1.0
    

    If you want to examine all float fields in all objects, it should be possible to use OQL's reflection capabilities to do so, using something like the following:

    select filter(heap.objects(), function(it) {
      var cls = classof(it);
      while (cls) {
        for (var i = 0; i < cls.fields.length; i++) {
          var field = cls.fields[i];
          if (field.signature == 'F' && it[field.name] == 0.0)
            return true;
          }
        cls = cls.superclass;
      }
      return false;
    })
    

    However, while this works correctly using jhat, it doesn't work in my version of VisualVM (1.6.0_22), because cls.fields seems to improperly return a list of static fields rather than instance fields.

    It's also very slow, taking 10 seconds to search a 1MB heap dump. It's probably possible to optimize the code and also speed things up by only searching a limited set of classes.