Send CloseableRef leaks to Flipper plugin (#455)
Summary: Pull Request resolved: https://github.com/facebook/flipper/pull/455 Only logging to the console for now, but it's a good start. Reviewed By: oprisnik Differential Revision: D15535820 fbshipit-source-id: 8531ec5ef681d01b2428a1f016b2a1d9f1589a34
This commit is contained in:
committed by
Facebook Github Bot
parent
7dc3525846
commit
faf19452eb
@@ -13,6 +13,7 @@ import com.facebook.common.internal.Predicate;
|
|||||||
import com.facebook.common.memory.manager.DebugMemoryManager;
|
import com.facebook.common.memory.manager.DebugMemoryManager;
|
||||||
import com.facebook.common.memory.manager.NoOpDebugMemoryManager;
|
import com.facebook.common.memory.manager.NoOpDebugMemoryManager;
|
||||||
import com.facebook.common.references.CloseableReference;
|
import com.facebook.common.references.CloseableReference;
|
||||||
|
import com.facebook.common.references.SharedReference;
|
||||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||||
import com.facebook.drawee.backends.pipeline.info.ImageLoadStatus;
|
import com.facebook.drawee.backends.pipeline.info.ImageLoadStatus;
|
||||||
import com.facebook.drawee.backends.pipeline.info.ImageOriginUtils;
|
import com.facebook.drawee.backends.pipeline.info.ImageOriginUtils;
|
||||||
@@ -31,28 +32,31 @@ import com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory;
|
|||||||
import com.facebook.imagepipeline.cache.CountingMemoryCacheInspector;
|
import com.facebook.imagepipeline.cache.CountingMemoryCacheInspector;
|
||||||
import com.facebook.imagepipeline.cache.CountingMemoryCacheInspector.DumpInfoEntry;
|
import com.facebook.imagepipeline.cache.CountingMemoryCacheInspector.DumpInfoEntry;
|
||||||
import com.facebook.imagepipeline.core.ImagePipelineFactory;
|
import com.facebook.imagepipeline.core.ImagePipelineFactory;
|
||||||
|
import com.facebook.imagepipeline.debug.CloseableReferenceLeakTracker;
|
||||||
import com.facebook.imagepipeline.debug.DebugImageTracker;
|
import com.facebook.imagepipeline.debug.DebugImageTracker;
|
||||||
import com.facebook.imagepipeline.debug.FlipperImageTracker;
|
import com.facebook.imagepipeline.debug.FlipperImageTracker;
|
||||||
import com.facebook.imagepipeline.image.CloseableBitmap;
|
import com.facebook.imagepipeline.image.CloseableBitmap;
|
||||||
import com.facebook.imagepipeline.image.CloseableImage;
|
import com.facebook.imagepipeline.image.CloseableImage;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows Sonar to display the contents of Fresco's caches. This is useful for developers to debug
|
* Allows Sonar to display the contents of Fresco's caches. This is useful for developers to debug
|
||||||
* what images are being held in cache as they navigate through their app.
|
* what images are being held in cache as they navigate through their app.
|
||||||
*/
|
*/
|
||||||
public class FrescoFlipperPlugin extends BufferingFlipperPlugin implements ImagePerfDataListener {
|
public class FrescoFlipperPlugin extends BufferingFlipperPlugin
|
||||||
|
implements ImagePerfDataListener, CloseableReferenceLeakTracker.Listener {
|
||||||
|
|
||||||
private static final String FRESCO_EVENT = "events";
|
private static final String FRESCO_EVENT = "events";
|
||||||
private static final String FRESCO_DEBUGOVERLAY_EVENT = "debug_overlay_event";
|
private static final String FRESCO_DEBUGOVERLAY_EVENT = "debug_overlay_event";
|
||||||
|
private static final String FRESCO_CLOSEABLE_REFERENCE_LEAK_EVENT =
|
||||||
|
"closeable_reference_leak_event";
|
||||||
|
|
||||||
private static final int BITMAP_PREVIEW_WIDTH = 150;
|
private static final int BITMAP_PREVIEW_WIDTH = 150;
|
||||||
private static final int BITMAP_PREVIEW_HEIGHT = 150;
|
private static final int BITMAP_PREVIEW_HEIGHT = 150;
|
||||||
@@ -82,7 +86,8 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin implements Image
|
|||||||
@Nullable FlipperObjectHelper flipperObjectHelper,
|
@Nullable FlipperObjectHelper flipperObjectHelper,
|
||||||
DebugMemoryManager memoryManager,
|
DebugMemoryManager memoryManager,
|
||||||
FlipperPerfLogger perfLogger,
|
FlipperPerfLogger perfLogger,
|
||||||
@Nullable FrescoFlipperDebugPrefHelper debugPrefHelper) {
|
@Nullable FrescoFlipperDebugPrefHelper debugPrefHelper,
|
||||||
|
@Nullable CloseableReferenceLeakTracker closeableReferenceLeakTracker) {
|
||||||
mFlipperImageTracker =
|
mFlipperImageTracker =
|
||||||
imageTracker instanceof FlipperImageTracker
|
imageTracker instanceof FlipperImageTracker
|
||||||
? (FlipperImageTracker) imageTracker
|
? (FlipperImageTracker) imageTracker
|
||||||
@@ -92,6 +97,10 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin implements Image
|
|||||||
mMemoryManager = memoryManager;
|
mMemoryManager = memoryManager;
|
||||||
mPerfLogger = perfLogger;
|
mPerfLogger = perfLogger;
|
||||||
mDebugPrefHelper = debugPrefHelper;
|
mDebugPrefHelper = debugPrefHelper;
|
||||||
|
|
||||||
|
if (closeableReferenceLeakTracker != null) {
|
||||||
|
closeableReferenceLeakTracker.setListener(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public FrescoFlipperPlugin() {
|
public FrescoFlipperPlugin() {
|
||||||
@@ -101,6 +110,7 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin implements Image
|
|||||||
null,
|
null,
|
||||||
new NoOpDebugMemoryManager(),
|
new NoOpDebugMemoryManager(),
|
||||||
new NoOpFlipperPerfLogger(),
|
new NoOpFlipperPerfLogger(),
|
||||||
|
null,
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +140,8 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin implements Image
|
|||||||
imagePipelineFactory.getBitmapCountingMemoryCache())
|
imagePipelineFactory.getBitmapCountingMemoryCache())
|
||||||
.dumpCacheContent();
|
.dumpCacheContent();
|
||||||
|
|
||||||
final FlipperArray memoryCacheSharedEntries = buildImageIdList(memoryCache.sharedEntries);
|
final FlipperArray memoryCacheSharedEntries =
|
||||||
|
buildImageIdList(memoryCache.sharedEntries);
|
||||||
final FlipperArray memoryCacheLRUEntries = buildImageIdList(memoryCache.lruEntries);
|
final FlipperArray memoryCacheLRUEntries = buildImageIdList(memoryCache.lruEntries);
|
||||||
final FlipperArray.Builder imageIDListBuilder = new FlipperArray.Builder();
|
final FlipperArray.Builder imageIDListBuilder = new FlipperArray.Builder();
|
||||||
for (int i = 0; i < memoryCacheSharedEntries.length(); ++i) {
|
for (int i = 0; i < memoryCacheSharedEntries.length(); ++i) {
|
||||||
@@ -433,7 +444,8 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin implements Image
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlipperImageTracker.ImageDebugData data = mFlipperImageTracker.getDebugDataForRequestId(requestId);
|
FlipperImageTracker.ImageDebugData data =
|
||||||
|
mFlipperImageTracker.getDebugDataForRequestId(requestId);
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -495,4 +507,13 @@ public class FrescoFlipperPlugin extends BufferingFlipperPlugin implements Image
|
|||||||
private static void respondError(FlipperResponder responder, String errorReason) {
|
private static void respondError(FlipperResponder responder, String errorReason) {
|
||||||
responder.error(new FlipperObject.Builder().put("reason", errorReason).build());
|
responder.error(new FlipperObject.Builder().put("reason", errorReason).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCloseableReferenceLeak(SharedReference<Closeable> reference) {
|
||||||
|
final FlipperObject.Builder builder =
|
||||||
|
new FlipperObject.Builder()
|
||||||
|
.put("identityHashCode", System.identityHashCode(reference))
|
||||||
|
.put("className", reference.get().getClass().getName());
|
||||||
|
send(FRESCO_CLOSEABLE_REFERENCE_LEAK_EVENT, builder.build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,3 +67,8 @@ export type ImageEvent = {
|
|||||||
export type FrescoDebugOverlayEvent = {|
|
export type FrescoDebugOverlayEvent = {|
|
||||||
enabled: boolean,
|
enabled: boolean,
|
||||||
|};
|
|};
|
||||||
|
|
||||||
|
export type AndroidCloseableReferenceLeakEvent = {|
|
||||||
|
identityHashCode: string,
|
||||||
|
className: string,
|
||||||
|
|};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import type {
|
|||||||
ImagesListResponse,
|
ImagesListResponse,
|
||||||
ImageEvent,
|
ImageEvent,
|
||||||
FrescoDebugOverlayEvent,
|
FrescoDebugOverlayEvent,
|
||||||
|
AndroidCloseableReferenceLeakEvent,
|
||||||
CacheInfo,
|
CacheInfo,
|
||||||
} from './api.js';
|
} from './api.js';
|
||||||
import type {ImagesMap} from './ImagePool.js';
|
import type {ImagesMap} from './ImagePool.js';
|
||||||
@@ -225,6 +226,13 @@ export default class extends FlipperPlugin<PluginState, *, PersistedState> {
|
|||||||
this.setState({isDebugOverlayEnabled: event.enabled});
|
this.setState({isDebugOverlayEnabled: event.enabled});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
this.client.subscribe(
|
||||||
|
'closeable_reference_leak_event',
|
||||||
|
(event: AndroidCloseableReferenceLeakEvent) => {
|
||||||
|
// TODO(T45065440): Temporary log, to be turned into counter.
|
||||||
|
console.warn('CloseableReference leak detected:', event);
|
||||||
|
},
|
||||||
|
);
|
||||||
this.imagePool = new ImagePool(this.getImage, (images: ImagesMap) =>
|
this.imagePool = new ImagePool(this.getImage, (images: ImagesMap) =>
|
||||||
this.props.setPersistedState({imagesMap: images}),
|
this.props.setPersistedState({imagesMap: images}),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user