java - Android Service 实例在 onDestroy() 和 GC 之后继续存在

标签 java android memory-leaks garbage-collection leakcanary

我创建了一个测试应用程序来查看 Android 的服务是否被正确回收。

我创建了一个服务,它只做一件事:保存对象的 WeakReference。这个想法是,在Service被销毁并调用GC之后,WeakReference应该返回null。这是我的服务:

package com.example.test.serviceleaktest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import java.lang.ref.WeakReference;


public class MyService extends Service {

    public static WeakReference sWeakReference = new WeakReference(null);

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        sWeakReference = new WeakReference("data");
        Log.d("asdf", "MyService started");
        return START_NOT_STICKY;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("asdf", "MyService created");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("asdf", "MyService destroyed");
    }

}

我使用 Context.startService() 启动服务并使用 Context.stopService() 停止它。 LogCat 确认调用了 onDestroy()。然后我进行 GC(从 LeakCanary 复制的代码):

Runtime.getRuntime().gc();
Thread.sleep(100);
System.runFinalization();

此时,我假设 sWeakReference.get() 应该返回 null,对吧?但它仍然返回指定的值。为什么?

最佳答案

The idea is, after the Service is destroyed and GC is called, the WeakReference should return null.

您似乎误解了WeakReference,或者至少我不清楚为什么您认为您提供的代码表现出了任何意外的行为。如果您创建一个指向某个对象oWeakReference,并且一段时间后GC确定o不是强可达的,那么GC将清除WeakReference

您正在创建一个指向String对象的WeakReference,该对象在源代码中表示为文字。如果 Java 使用该 String 的内部版本(它很可能会这样做),那么它可能会选择将其视为始终强可达,以便引用对象永远不会被清除。

由于您说您想要监视 Service 的清理,并且您提供了 Service 的子类,因此我倾向于认为您正在监视创建弱引用的对象的清理。这不是它的工作方式。

如果您确实想要监视Service 的清理,那么您需要创建一个到服务对象的WeakReference。在您当前的代码中,其拼写为 new WeakReference(this)

另请注意,监视对象何时不再可强访问是 ReferenceQueue 的目的。如果您创建一个 ReferenceQueue 并向其注册您的 WeakReference,那么您可以监视要排队的弱引用,而不用测试其目标是否已清除。

关于java - Android Service 实例在 onDestroy() 和 GC 之后继续存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34165622/

相关文章:

objective-c - iOS libsystem_c.dylib strdup 内存泄漏 NSZombie 不工作

android - Picasso 和 FragmentStatePagerAdapter 的内存泄漏

java - 为什么我在jdk9 win10下无法运行struts2.5.13

java - JSF 2 - 如何使用 JSF EL 从 web.xml 获取上下文参数值?

c# - Android(c2dm)推送通知错误

安卓蜂窝 : NetworkOnMainThreadException even when using AsyncTask and no strict mode?

java - 如何在 Vaadin Binder 中确认验证

java - 图像未显示在 JFrame 中

android - 以编程方式在 fragment 之间切换

performance - GRAILS 2,内存问题