首页 > 解决方案 > 线程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() 调用:

  1. 告诉当前正在执行的线程进入睡眠状态(不使用任何 CPU)。

  2. 释放锁,以便其他线程可以唤醒并获取锁。

似乎 wait() 也会导致持有局部变量。我以前没有意识到这一点。这些局部变量在哪里?它还在“VM Stack”中吗?有更多关于这个的教程吗?

=================更新=======================

SmartConfigMainActivity 与 NetworkDetector 没有任何关系。我认为 Message 在 Looper 中被重用,这导致了这种内存泄漏。但我无法控制 android 的这种重用行为。如我所见,jvm应该保存局部变量以防止它被gc,因为当wait()返回时,它应该回到原始状态并使用这些变量。但我没有看到任何关于这个的教程

标签: javaandroidmultithreadingmemory-leaks

解决方案


推荐阅读