java - 线程wait()时局部变量依然会导致内存泄漏
问题描述
我在以下代码中遇到了内存泄漏:
@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 根,持有本地变量,例如 Message。因此,来自链接的 wait() 调用:
告诉当前正在执行的线程进入睡眠状态(不使用任何 CPU)。
释放锁,以便其他线程可以唤醒并获取锁。
似乎 wait() 也会导致持有局部变量。我以前没有意识到这一点。这些局部变量在哪里?它还在“VM Stack”中吗?有更多关于这个的教程吗?
=================更新=======================
SmartConfigMainActivity 与 NetworkDetector 没有任何关系。我认为 Message 在 Looper 中被重用,这导致了这种内存泄漏。但我无法控制 android 的这种重用行为。如我所见,jvm应该保存局部变量以防止它被gc,因为当wait()返回时,它应该回到原始状态并使用这些变量。但我没有看到任何关于这个的教程
解决方案
推荐阅读
- mongodb - MongoDB查询以查找嵌套数组中的列表
- asp.net - 电子邮件确认后如何将用户重定向到主页?
- amazon-web-services - 使用 aws java sdk 版本 2 从资源文件夹中读取 aws 配置和凭据
- database - 布尔表达式不能为空?
- asp.net - 通过 Microsoft Graph 访问共享邮箱 - “访问被拒绝”
- java - C#如何关闭所有子进程
- javascript - firebase.firestore() .set() 没有第一次触发
- javascript - 如何在节点 js 中记录特定的错误消息?
- javascript - Vue.js:访问另一个组件中的数组数据
- c# - 如何返回 IEnumerable
/IL 列表 为 null 或使用 null-coalescing 运算符的值