优化 opencv内存泄漏问题

This commit is contained in:
hyb1996
2018-10-24 20:39:51 +08:00
parent dbcb0257a2
commit 8864e78af6
14 changed files with 304 additions and 27 deletions

View File

@@ -2,6 +2,7 @@
var url = "https://www.autojs.org/assets/uploads/profile/3-profileavatar.png";
var logo = null;
var currentImg = null;
ui.layout(
<vertical>
@@ -18,7 +19,14 @@ ui.layout(
//把一张图片设置到图片控件中
function setImage(img) {
ui.run(() => {
var curImg = currentImg;
if(oldImg != null){
ui.post(()=>{
oldImg.recycle();
});
}
ui.img.setImageBitmap(img.bitmap);
currentImg = img;
});
}
@@ -63,20 +71,20 @@ ui.hsv.on("click", () => {
ui.blur.on("click", () => {
processImg(img => {
//RGB转HSV
//模糊
return images.blur(img, [10, 10]);
});
});
ui.medianBlur.on("click", () => {
processImg(img => {
//RGB转HSV
return images.medianBlur(img, 10);
//中值滤波
return images.medianBlur(img, 5);
});
});
ui.gaussianBlur.on("click", () => {
processImg(img => {
//RGB转HSV
//高斯模糊
return images.gaussianBlur(img, [5, 5]);
});
});

View File

@@ -14,7 +14,6 @@ import com.bumptech.glide.request.transition.Transition;
import com.flurry.android.FlurryAgent;
import com.squareup.leakcanary.LeakCanary;
import com.stardust.app.GlobalAppContext;
import com.stardust.autojs.core.image.OpenCVHelper;
import com.stardust.autojs.core.ui.inflater.ImageLoader;
import com.stardust.autojs.core.ui.inflater.util.Drawables;
import com.stardust.theme.ThemeColor;
@@ -31,8 +30,6 @@ import org.autojs.autojs.timing.TimedTaskManager;
import org.autojs.autojs.timing.TimedTaskScheduler;
import org.autojs.autojs.tool.CrashHandler;
import org.autojs.autojs.ui.error.ErrorReportActivity;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.OpenCVLoader;
import java.lang.ref.WeakReference;
import java.util.ArrayList;

View File

@@ -45,8 +45,7 @@ import static org.autojs.autojs.ui.edit.EditorView.EXTRA_READ_ONLY;
* Created by Stardust on 2017/1/29.
*/
@EActivity(R.layout.activity_edit)
public class
EditActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHost, PermissionRequestProxyActivity {
public class EditActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHost, PermissionRequestProxyActivity {
private OnActivityResultDelegate.Mediator mMediator = new OnActivityResultDelegate.Mediator();
private static final String LOG_TAG = "EditActivity";

View File

@@ -9,7 +9,7 @@ import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import com.stardust.autojs.core.image.OpenCVHelper;
import com.stardust.autojs.core.opencv.OpenCVHelper;
import com.xcy8.ads.listener.LoadAdListener;
import com.xcy8.ads.view.FullScreenAdView;

View File

@@ -283,7 +283,7 @@ module.exports = function (__runtime__, scope) {
}
function newMat() {
return new org.opencv.core.Mat();
return new com.stardust.autojs.core.opencv.Mat();
}
function matToImage(mat) {

View File

@@ -4,11 +4,14 @@ import android.graphics.Color;
import android.os.Build;
import android.support.annotation.RequiresApi;
import com.stardust.autojs.core.opencv.MatOfPoint;
import com.stardust.autojs.core.opencv.OpenCVHelper;
import com.stardust.util.ScreenMetrics;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import com.stardust.autojs.core.opencv.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
@@ -48,6 +51,7 @@ public class ColorFinder {
point.x = mScreenMetrics.scaleX((int) (point.x + rect.x));
point.y = mScreenMetrics.scaleX((int) (point.y + rect.y));
}
OpenCVHelper.release(matOfPoint);
return point;
}
@@ -86,7 +90,7 @@ public class ColorFinder {
if (nonZeroPos.rows() == 0 || nonZeroPos.cols() == 0) {
result = null;
} else {
result = new MatOfPoint(nonZeroPos);
result = OpenCVHelper.newMatOfPoint(nonZeroPos);
}
OpenCVHelper.release(bi);
OpenCVHelper.release(nonZeroPos);
@@ -114,7 +118,7 @@ public class ColorFinder {
x += startingPoint.x;
y += startingPoint.y;
if (x >= image.getWidth() || y >= image.getHeight()
|| x < 0 || y < 0) {
|| x < 0 || y < 0) {
return false;
}
int c = image.pixel(x, y);

View File

@@ -6,10 +6,11 @@ import android.media.Image;
import android.os.Build;
import android.support.annotation.RequiresApi;
import com.stardust.autojs.core.opencv.OpenCVHelper;
import com.stardust.pio.UncheckedIOException;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import com.stardust.autojs.core.opencv.Mat;
import org.opencv.highgui.Highgui;
import java.io.FileNotFoundException;

View File

@@ -1,14 +1,14 @@
package com.stardust.autojs.core.image;
import android.util.Log;
import android.util.Pair;
import android.util.TimingLogger;
import com.stardust.autojs.core.opencv.OpenCVHelper;
import com.stardust.util.Nath;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import com.stardust.autojs.core.opencv.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Size;
@@ -100,6 +100,7 @@ public class TemplateMatching {
}
logger.addSplit("result:" + p);
logger.dumpToLog();
OpenCVHelper.release(matchResult);
if (similarity < strictThreshold) {
return null;
}

View File

@@ -0,0 +1,108 @@
package com.stardust.autojs.core.opencv;
import com.stardust.util.ResourceMonitor;
import org.opencv.core.Range;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicInteger;
public class Mat extends org.opencv.core.Mat implements ResourceMonitor.Resource {
private static Method nClone;
static {
try {
nClone = org.opencv.core.Mat.class.getDeclaredMethod("n_clone", long.class);
nClone.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
private static final AtomicInteger sResourceId = new AtomicInteger();
private volatile boolean mReleased = false;
private final int mResourceId = sResourceId.incrementAndGet();
public Mat(long addr) {
super(addr);
ResourceMonitor.onOpen(this);
}
public Mat() {
super();
ResourceMonitor.onOpen(this);
}
public Mat(int rows, int cols, int type) {
super(rows, cols, type);
ResourceMonitor.onOpen(this);
}
public Mat(Size size, int type) {
super(size, type);
ResourceMonitor.onOpen(this);
}
public Mat(int rows, int cols, int type, Scalar s) {
super(rows, cols, type, s);
ResourceMonitor.onOpen(this);
}
public Mat(Size size, int type, Scalar s) {
super(size, type, s);
ResourceMonitor.onOpen(this);
}
public Mat(Mat m, Range rowRange, Range colRange) {
super(m, rowRange, colRange);
ResourceMonitor.onOpen(this);
}
public Mat(Mat m, Range rowRange) {
super(m, rowRange);
ResourceMonitor.onOpen(this);
}
public Mat(Mat m, Rect roi) {
super(m, roi);
ResourceMonitor.onOpen(this);
}
@Override
public Mat clone() {
return new Mat(n_clone(this.nativeObj));
}
protected long n_clone(long addr) {
try {
return (long) nClone.invoke(this, addr);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void release() {
super.release();
mReleased = true;
ResourceMonitor.onClose(this);
}
@Override
protected void finalize() throws Throwable {
if (!mReleased) {
ResourceMonitor.onFinalize(this);
super.release();
}
super.finalize();
}
@Override
public int getResourceId() {
return mResourceId;
}
}

View File

@@ -0,0 +1,56 @@
package com.stardust.autojs.core.opencv;
import com.stardust.util.ResourceMonitor;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import java.util.concurrent.atomic.AtomicInteger;
public class MatOfPoint extends org.opencv.core.MatOfPoint implements ResourceMonitor.Resource {
private static final AtomicInteger sResourceId = new AtomicInteger();
private volatile boolean mReleased = false;
private final int mResourceId = sResourceId.incrementAndGet();
public MatOfPoint() {
super();
ResourceMonitor.onOpen(this);
}
public MatOfPoint(long addr) {
super(addr);
ResourceMonitor.onOpen(this);
}
public MatOfPoint(Mat m) {
super(m);
ResourceMonitor.onOpen(this);
}
public MatOfPoint(Point... a) {
super(a);
ResourceMonitor.onOpen(this);
}
@Override
public void release() {
super.release();
mReleased = true;
ResourceMonitor.onClose(this);
}
@Override
protected void finalize() throws Throwable {
if (!mReleased) {
ResourceMonitor.onFinalize(this);
super.release();
}
super.finalize();
}
@Override
public int getResourceId() {
return mResourceId;
}
}

View File

@@ -1,4 +1,4 @@
package com.stardust.autojs.core.image;
package com.stardust.autojs.core.opencv;
import android.app.Activity;
import android.support.annotation.Nullable;
@@ -9,7 +9,7 @@ import com.afollestad.materialdialogs.MaterialDialog;
import org.opencv.android.InstallCallbackInterface;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
/**
* Created by Stardust on 2018/4/2.
@@ -24,6 +24,17 @@ public class OpenCVHelper {
private static final String LOG_TAG = "OpenCVHelper";
private static boolean mInitialized = false;
public static MatOfPoint newMatOfPoint(Mat mat){
return new MatOfPoint(mat);
}
public static void release(@Nullable MatOfPoint mat) {
if (mat == null)
return;
mat.release();
}
public static void release(@Nullable Mat mat) {
if (mat == null)
return;

View File

@@ -12,14 +12,12 @@ import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.util.Base64;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
import android.widget.ListView;
import com.stardust.autojs.annotation.ScriptVariable;
import com.stardust.autojs.core.image.ColorFinder;
import com.stardust.autojs.core.image.ImageWrapper;
import com.stardust.autojs.core.image.OpenCVHelper;
import com.stardust.autojs.core.opencv.OpenCVHelper;
import com.stardust.autojs.core.image.capture.ScreenCaptureRequester;
import com.stardust.autojs.core.image.capture.ScreenCapturer;
import com.stardust.autojs.core.image.TemplateMatching;
@@ -30,11 +28,9 @@ import com.stardust.concurrent.VolatileDispose;
import com.stardust.pio.UncheckedIOException;
import com.stardust.util.ScreenMetrics;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import com.stardust.autojs.core.opencv.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.imgproc.Imgproc;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;

View File

@@ -0,0 +1,96 @@
// ResourceMonitor$onFinalize$1.java
package com.stardust.util;
import android.os.Handler;
import android.os.Looper;
import android.util.SparseArray;
import com.stardust.BuildConfig;
import java.util.concurrent.ConcurrentHashMap;
public final class ResourceMonitor {
private static final String LOG_TAG = "ResourceTracer";
private static final ConcurrentHashMap<Class<?>, SparseArray<UnclosedResourceException>> mResources;
private static Handler mHandler;
private static boolean mEnabled;
public static void onOpen(ResourceMonitor.Resource resource) {
if (!mEnabled) {
return;
}
SparseArray<UnclosedResourceException> map = mResources.get(resource.getClass());
if (map == null) {
map = new SparseArray<>();
mResources.put(resource.getClass(), map);
}
int resourceId = resource.getResourceId();
ResourceMonitor.UnclosedResourceException exception = new ResourceMonitor.UnclosedResourceException("id = " + resourceId + ", resource = " + resource);
exception.fillInStackTrace();
map.put(resourceId, exception);
}
public static void onClose(ResourceMonitor.Resource resource) {
if (!mEnabled) {
return;
}
SparseArray map = mResources.get(resource.getClass());
if (map != null) {
map.remove(resource.getResourceId());
}
}
public static void onFinalize(ResourceMonitor.Resource resource) {
if (!mEnabled) {
return;
}
SparseArray<UnclosedResourceException> map = mResources.get(resource.getClass());
if (map != null) {
int indexOfKey = map.indexOfKey(resource.getResourceId());
if (indexOfKey >= 0) {
final ResourceMonitor.UnclosedResourceException unclosedResourceException = map.valueAt(indexOfKey);
map.removeAt(indexOfKey);
if (mHandler == null) {
mHandler = new Handler(Looper.getMainLooper());
}
mHandler.post(new Runnable() {
public final void run() {
throw new UnclosedResourceDetectedException(unclosedResourceException);
}
});
}
}
}
static {
mResources = new ConcurrentHashMap<>();
mEnabled = BuildConfig.DEBUG;
}
public static boolean isEnabled() {
return mEnabled;
}
public static void setEnabled(boolean mEnabled) {
ResourceMonitor.mEnabled = mEnabled;
}
public static final class UnclosedResourceException extends RuntimeException {
public UnclosedResourceException(String message) {
super(message);
}
}
public static final class UnclosedResourceDetectedException extends RuntimeException {
public UnclosedResourceDetectedException(ResourceMonitor.UnclosedResourceException cause) {
super(cause);
}
}
public interface Resource {
int getResourceId();
}
}

View File

@@ -16,7 +16,7 @@ import android.widget.Toast;
import com.stardust.auojs.inrt.autojs.AutoJs;
import com.stardust.auojs.inrt.launch.GlobalProjectLauncher;
import com.stardust.autojs.core.image.OpenCVHelper;
import com.stardust.autojs.core.opencv.OpenCVHelper;
import java.util.ArrayList;
import java.util.List;