修复部分内存泄露问题

This commit is contained in:
TonyJiangWJ 2020-05-26 01:23:44 +08:00
parent 965839875f
commit f41cab18d4
5 changed files with 38 additions and 7 deletions

View File

@ -1,7 +1,10 @@
package com.stardust.autojs.core.looper;
import android.os.Build;
import android.os.Looper;
import androidx.annotation.RequiresApi;
import java.util.concurrent.ConcurrentHashMap;
/**

View File

@ -173,6 +173,7 @@ public class Loopers implements MessageQueue.IdleHandler {
public void recycle() {
quitServantLooper();
mMainMessageQueue.removeIdleHandler(this);
removeThreadLocalValue();
}
public void setMainLooperQuitHandler(LooperQuitHandler mainLooperQuitHandler) {
@ -195,11 +196,19 @@ public class Loopers implements MessageQueue.IdleHandler {
Log.d(LOG_TAG, "looper queueIdle: " + l);
if (shouldQuitLooper()) {
l.quit();
removeThreadLocalValue();
}
}
return true;
}
private void removeThreadLocalValue() {
maxWaitId.remove();
waitIds.remove();
looperQuitHandlers.remove();
maxWaitId.remove();
}
public void prepare() {
if (Looper.myLooper() == null)
LooperHelper.prepare();

View File

@ -10,6 +10,8 @@ import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.concurrent.VolatileBox;
import com.stardust.lang.ThreadCompat;
import org.mozilla.javascript.Context;
import java.util.concurrent.ConcurrentHashMap;
/**
@ -37,12 +39,12 @@ public class TimerThread extends ThreadCompat {
@Override
public void run() {
mRuntime.loopers.prepare();
mTimer = new Timer(mRuntime, mMaxCallbackUptimeMillisForAllThreads);
sTimerMap.put(Thread.currentThread(), mTimer);
((RhinoJavaScriptEngine) mRuntime.engines.myEngine()).enterContext();
Context engineContext = ((RhinoJavaScriptEngine) mRuntime.engines.myEngine()).enterContext();
notifyRunning();
new Handler().post(mTarget);
try {
mTimer = new Timer(mRuntime, mMaxCallbackUptimeMillisForAllThreads);
sTimerMap.put(Thread.currentThread(), mTimer);
Looper.loop();
} catch (Throwable e) {
if (!ScriptInterruptedException.causedByInterrupted(e)) {
@ -50,9 +52,9 @@ public class TimerThread extends ThreadCompat {
}
} finally {
onExit();
mTimer = null;
org.mozilla.javascript.Context.exit();
((RhinoJavaScriptEngine)mRuntime.engines.myEngine()).exitContext(engineContext);
sTimerMap.remove(Thread.currentThread(), mTimer);
mTimer = null;
}
}
@ -72,6 +74,7 @@ public class TimerThread extends ThreadCompat {
@CallSuper
protected void onExit() {
mRuntime.loopers.notifyThreadExit(this);
LooperHelper.quitForThread(this);
}
public static Timer getTimerForThread(Thread thread) {

View File

@ -12,7 +12,10 @@ import com.stardust.autojs.runtime.ScriptRuntime
import com.stardust.autojs.script.JavaScriptSource
import com.stardust.automator.UiObjectCollection
import com.stardust.pio.UncheckedIOException
import org.mozilla.javascript.*
import org.mozilla.javascript.Context
import org.mozilla.javascript.Script
import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.ScriptableObject
import org.mozilla.javascript.commonjs.module.RequireBuilder
import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider
import java.io.File
@ -153,6 +156,15 @@ open class RhinoJavaScriptEngine(private val mAndroidContext: android.content.Co
return context
}
fun exitContext(context: Context) {
sContextEngineMap.remove(context)
try {
Context.exit()
} catch (e: Exception) {
// do nothing
}
}
protected fun setupContext(context: Context) {
context.optimizationLevel = -1
context.languageVersion = Context.VERSION_ES6

View File

@ -53,7 +53,9 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
mCacheDir = dir;
mLibsDir = new File(dir, "libs");
if (dir.exists()) {
PFiles.deleteFilesOfDir(dir);
if (!(parent instanceof AndroidClassLoader)) {
PFiles.deleteFilesOfDir(dir);
}
} else {
dir.mkdirs();
}
@ -136,6 +138,7 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
if (!file.exists()) {
throw new FileNotFoundException(file.getPath());
}
Log.d(LOG_TAG, "dex file size: " + file.length());
DexClassLoader loader = new DexClassLoader(file.getPath(), mCacheDir.getPath(), mLibsDir.getPath(), parent);
// 根据dex文件名 移除已有的使得最新载入的在LinkedHashMap末尾
mDexClassLoaders.remove(file.getName());
@ -167,6 +170,7 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
arguments.outName = dexFile.getPath();
arguments.jarOutput = true;
Main.run(arguments);
Log.d(LOG_TAG, "dex file size: " + dexFile.length());
DexClassLoader loader = loadDex(dexFile);
if (isTmpDex) {
Log.d(LOG_TAG, "delete tmpFile on finalize:" + dexFile.getName());