From d43916b5551ac60d39e505fd02ede2484a1389c7 Mon Sep 17 00:00:00 2001 From: Diego Perez Date: Tue, 14 Jun 2016 17:50:45 +0100 Subject: [PATCH] Fix leak in VPathRenderer The pointer to the root group in the VPathRenderer is not freed anywhere in the Java side so we need to take care of it on the "native" side. Change-Id: I2ca60b1f0e975a0b5d29799c5f6f31b5f8d42b9d (cherry picked from commit ffdb1b241d9458196403c8f16264aa7053487323) --- .../graphics/drawable/VectorDrawable_Delegate.java | 31 +++++++++++++--------- .../layoutlib/bridge/impl/DelegateManager.java | 1 + .../android/layoutlib/bridge/intensive/Main.java | 4 +++ 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java index 1dfd305a6094..2903e3a4b445 100644 --- a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java @@ -91,16 +91,14 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static long nCreateTree(long rootGroupPtr) { - VGroup_Delegate rootGroup = VNativeObject.getDelegate(rootGroupPtr); - return sPathManager.addNewDelegate(new VPathRenderer_Delegate(rootGroup)); + return sPathManager.addNewDelegate(new VPathRenderer_Delegate(rootGroupPtr)); } @LayoutlibDelegate static long nCreateTreeFromCopy(long rendererToCopyPtr, long rootGroupPtr) { - VGroup_Delegate rootGroup = VNativeObject.getDelegate(rootGroupPtr); VPathRenderer_Delegate rendererToCopy = VNativeObject.getDelegate(rendererToCopyPtr); return sPathManager.addNewDelegate(new VPathRenderer_Delegate(rendererToCopy, - rootGroup)); + rootGroupPtr)); } @LayoutlibDelegate @@ -163,7 +161,6 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static long nCreateFullPath(long nativeFullPathPtr) { VFullPath_Delegate original = VNativeObject.getDelegate(nativeFullPathPtr); - return sPathManager.addNewDelegate(new VFullPath_Delegate(original)); } @@ -247,8 +244,7 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static long nCreateGroup(long groupPtr) { VGroup_Delegate original = VNativeObject.getDelegate(groupPtr); - return sPathManager.addNewDelegate( - new VGroup_Delegate(original, new ArrayMap())); + return sPathManager.addNewDelegate(new VGroup_Delegate(original, new ArrayMap<>())); } @LayoutlibDelegate @@ -1029,7 +1025,7 @@ public class VectorDrawable_Delegate { private final Path mPath; private final Path mRenderPath; private final Matrix mFinalPathMatrix = new Matrix(); - private final VGroup_Delegate mRootGroup; + private final long mRootGroupPtr; private float mViewportWidth = 0; private float mViewportHeight = 0; private float mRootAlpha = 1.0f; @@ -1037,15 +1033,15 @@ public class VectorDrawable_Delegate { private Paint mFillPaint; private PathMeasure mPathMeasure; - private VPathRenderer_Delegate(VGroup_Delegate rootGroup) { - mRootGroup = rootGroup; + private VPathRenderer_Delegate(long rootGroupPtr) { + mRootGroupPtr = rootGroupPtr; mPath = new Path(); mRenderPath = new Path(); } private VPathRenderer_Delegate(VPathRenderer_Delegate rendererToCopy, - VGroup_Delegate rootGroup) { - this(rootGroup); + long rootGroupPtr) { + this(rootGroupPtr); mViewportWidth = rendererToCopy.mViewportWidth; mViewportHeight = rendererToCopy.mViewportHeight; mRootAlpha = rendererToCopy.mRootAlpha; @@ -1087,7 +1083,7 @@ public class VectorDrawable_Delegate { public void draw(long canvasPtr, long filterPtr, int w, int h) { // Traverse the tree in pre-order to draw. - drawGroupTree(mRootGroup, Matrix.IDENTITY_MATRIX, canvasPtr, w, h, filterPtr); + drawGroupTree(VNativeObject.getDelegate(mRootGroupPtr), Matrix.IDENTITY_MATRIX, canvasPtr, w, h, filterPtr); } private void drawPath(VGroup_Delegate VGroup, VPath_Delegate VPath, long canvasPtr, @@ -1227,5 +1223,14 @@ public class VectorDrawable_Delegate { @Override public void setName(String name) { } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + + // The mRootGroupPtr is not explicitly freed by anything in the VectorDrawable so we + // need to free it here. + sPathManager.removeJavaReferenceFor(mRootGroupPtr); + } } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java index 0c39026a15d8..ea40ba78e58a 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java @@ -165,5 +165,6 @@ public final class DelegateManager { int idx = sDelegates.indexOfValue(reference); out.printf("[%d] %s\n", sDelegates.keyAt(idx), reference.getClass().getSimpleName()); } + out.printf("\nTotal number of objects: %d\n", sJavaReferences.size()); } } diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java index ba687fe384e6..d16026845db1 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java @@ -349,7 +349,11 @@ public class Main { obj = null; while(ref.get() != null) { System.gc(); + System.runFinalization(); } + + System.gc(); + System.runFinalization(); } @AfterClass -- 2.11.0