2

I can query all the instances of com.google.common.cache.LocalCache$StrongAccessWriteEntry in mat using OQL:

SELECT * FROM com.google.common.cache.LocalCache$StrongAccessWriteEntry

I've turned on Keep unreachable objects in mat. So the result contains both reachable and unreachable objects. Now I want to get all the unreachable com.google.common.cache.LocalCache$StrongAccessWriteEntry instances(aka. no gc roots), something like this:

SELECT * FROM com.google.common.cache.LocalCache$StrongAccessWriteEntry WHERE unreachable=true

Can I do it using OQL?

Searene
  • 25,920
  • 39
  • 129
  • 186

2 Answers2

5

Yes, a query such as:

SELECT * FROM com.google.common.cache.LocalCache$StrongAccessWriteEntry r where r in (SELECT AS RETAINED SET objects s FROM OBJECTS ${snapshot}.@GCRoots s WHERE ((SELECT t FROM OBJECTS ${snapshot}.getGCRootInfo(s) t WHERE (t.@type = 2048)) != null))

should do it.

Explanation:

Find the GC roots:

SELECT objects s FROM OBJECTS ${snapshot}.@GCRoots s

Find the GC roots, then for each GC root get the array of GC root information, then look at each GCRootInfo and find the type and see if it is Type.UNREACHABLE (2048) and only then select a GC root where the GC root information says it is unreachable. This finds the unreachable object roots. Keep unreachable objects only marks some of the unreachable objects as GC roots - the remaining unreachable objects are retained by these roots. Queries work better than way.

SELECT OBJECTS s FROM OBJECTS ${snapshot}.@GCRoots s WHERE ((SELECT t FROM OBJECTS ${snapshot}.getGCRootInfo(s) t WHERE (t.@type = 2048)) != null)

Find all the unreachable objects by finding all the objects retained by the unreachable GC roots:

SELECT AS RETAINED SET OBJECTS s FROM OBJECTS ${snapshot}.@GCRoots s WHERE ((SELECT t FROM OBJECTS ${snapshot}.getGCRootInfo(s) t WHERE (t.@type = 2048)) != null)

Find all the LocalCache$StrongAccessWriteEntry objects

SELECT * FROM com.google.common.cache.LocalCache$StrongAccessWriteEntry r

Find all the LocalCache$StrongAccessWriteEntry objects which are also in the unreachable objects set.

SELECT * FROM com.google.common.cache.LocalCache$StrongAccessWriteEntry r where r in (SELECT AS RETAINED SET OBJECTS s FROM OBJECTS ${snapshot}.@GCRoots s WHERE ((SELECT t FROM OBJECTS ${snapshot}.getGCRootInfo(s) t WHERE (t.@type = 2048)) != null))

There is more information about writing queries in the Eclipse Memory Analyzer wiki.

user13762112
  • 401
  • 3
  • 7
0

Unreachable objects means it has no incoming reference.

SELECT * 
FROM com.google.common.cache.LocalCache$StrongAccessWriteEntry o 
WHERE (inbounds(o).size() = 0)
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
X. Wu
  • 1
  • 1