Я обнаружил утечку памяти в следующем коде:
@Override
public void run() {
while (true) {
if(!isRunning) {
break;
}
ThreadHandler handler = threadHandlerRef.get();
if(handler == null) {
break;
}
handler.sendMessage(Message.obtain(handler, 1, this));
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Утечка памяти, как показано ниже:
In com.****.****:4.2.10:6796.
* com.****.****.SmartConfigMainActivity has leaked:
* GC ROOT com.****.****..NetworkDetector$DThread.<Java Local>
* references android.os.Message.obj
* references com.****.****.$3.a
* references com.****.****.mCommonBindView
* references com.****.****.CommonBindView.mContext
* leaks com.****.****. instance
Поток, как корень gc, содержит локальныйпеременные, такие как сообщение.Таким образом, вызов wait () по ссылке :
сообщает текущему исполняющемуся потоку, что он переходит в спящий режим (не использует процессор).
снимает блокировку, чтобы другие потоки могли проснуться и захватить блокировку.
Кажется, что wait () также приводит к удержанию локальных переменных.Я не осознавал этого раньше.Где эти локальные переменные?Это все еще в "VM Stack"?Есть ли еще учебник по этому поводу?
================= ОБНОВЛЕНИЕ =======================
SmartConfigMainActivity не имеет никаких связей с NetworkDetector.Я думаю, что Сообщение повторно используется в Looper, который вызвал эту утечку памяти.Но я не могу контролировать это повторное использование поведения Android.Как я вижу, jvm должен сохранить локальную переменную, чтобы предотвратить ее от gc, потому что когда wait () возвращается, он должен вернуться в исходное состояние и использовать эти переменные.Но я не видел ни одного учебника по этому поводу