Tencent/matrix · error · IllegalStateException
Unabled to find destroy activity info class with name:
Error message
Unabled to find destroy activity info class with name:
What it means
ActivityLeakAnalyzer looks up the DestroyedActivityInfo class in the heap dump snapshot to find keyed references to destroyed activities. If that class is absent from the dump, the analyzer cannot locate leak candidates and throws IllegalStateException. This usually means the Matrix resource monitoring was not active at capture time, so no destroyed-activity info instances were ever created.
Solutions
- Ensure the ResourcePlugin is installed and has detected at least one destroyed activity before the hprof is taken.
- Check ProGuard/R8 keep rules so DestroyedActivityInfo is not renamed/stripped.
- Verify you are analyzing the hprof from the app process where the leak was suspected.
- Confirm DESTROYED_ACTIVITY_INFO_CLASSNAME matches the class actually present (no package relocation between versions).
Example fix
// before
final ClassObj infoClass = snapshot.findClass(DESTROYED_ACTIVITY_INFO_CLASSNAME);
if (infoClass == null) {
throw new IllegalStateException("Unabled to find destroy activity info class with name: " + DESTROYED_ACTIVITY_INFO_CLASSNAME);
}
// after
final ClassObj infoClass = snapshot.findClass(DESTROYED_ACTIVITY_INFO_CLASSNAME);
if (infoClass == null) {
return null; // no destroyed-activity info recorded; report 'no leak found'
} Defensive patterns
Strategy: validation
Validate before calling
if (snapshot.findClass(DESTROYED_ACTIVITY_INFO_CLASSNAME) == null) { reportNoLeak("class absent from dump"); return; } Try / catch
try { ref = findLeakingReference(key, snapshot); } catch (IllegalStateException e) { log.warn("no destroyed-activity info in dump", e); return ActivityLeakResult.noLeak(); } Prevention
- Install ResourcePlugin before captures; confirm destroyed activities were recorded
- Add keep rules for DestroyedActivityInfo under obfuscation
- Analyze the hprof from the correct process/session
When it happens
Trigger: findLeakingReference runs snapshot.findClass(DESTROYED_ACTIVITY_INFO_CLASSNAME) and it returns null — the class was never loaded in the dumped process because the leak-monitor hook never recorded a destroyed activity, or the dump comes from a process where the class was stripped/renamed.
Common situations: Heap dumps captured before Matrix's ResourcePlugin initialized; dumps from builds without the resource-canary instrumentation; obfuscation (ProGuard/R8) renaming or removing DestroyedActivityInfo; analyzing a dump from the wrong process.
Related errors
- Could not find weak reference with key
- Unsupported reference type $value
- Unsupported object type $value
- free space($freeSpace) less than $CLEAN_THRESHOLD, skip…
- closer == null
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/75856040be475b88.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-resource-canary/matrix-resource-canary-analyzer/src/main/java/com/tencent/matrix/resource/analyzer/ActivityLeakAnalyzer.java:89
final Snapshot snapshot = heapSnapshot.getSnapshot();
final Instance leakingRef = findLeakingReference(refKey, snapshot);
// False alarm, weak reference was cleared in between key check and heap dump.
if (leakingRef == null) {
return ActivityLeakResult.noLeak(AnalyzeUtil.since(analysisStartNanoTime));
}
return findLeakTrace(analysisStartNanoTime, snapshot, leakingRef);
} catch (Throwable e) {
e.printStackTrace();
return ActivityLeakResult.failure(e, AnalyzeUtil.since(analysisStartNanoTime));
}
}
private Instance findLeakingReference(String key, Snapshot snapshot) {
final ClassObj infoClass = snapshot.findClass(DESTROYED_ACTIVITY_INFO_CLASSNAME);
if (infoClass == null) {
throw new IllegalStateException("Unabled to find destroy activity info class with name: "
+ DESTROYED_ACTIVITY_INFO_CLASSNAME);
}
List<String> keysFound = new ArrayList<>();
for (Instance infoInstance : infoClass.getInstancesList()) {
final List<ClassInstance.FieldValue> values = classInstanceValues(infoInstance);
final String keyCandidate = asString(fieldValue(values, ACTIVITY_REFERENCE_KEY_FIELDNAME));
if (keyCandidate.equals(key)) {
final Instance weakRefObj = fieldValue(values, ACTIVITY_REFERENCE_FIELDNAME);
if (weakRefObj == null) {
continue;
}
final List<ClassInstance.FieldValue> activityRefs = classInstanceValues(weakRefObj);
return fieldValue(activityRefs, "referent");
}
keysFound.add(keyCandidate);
}
throw new IllegalStateException(
"Could not find weak reference with key " + key + " in " + keysFound);View on GitHub (pinned to 3b8293bd65)