返回

内存管理(二):强引用分析

IOS

强引用是Java虚拟机(JVM)中用来管理对象内存分配和回收的一种引用类型。当一个对象被强引用时,JVM不会回收该对象,直到程序不再使用该对象。强引用是Java中最为常见的引用类型,也是最容易理解的引用类型。

在内存管理(一)中,我们讨论了强引用的基本概念,以及如何使用强引用来防止对象被回收。在本篇博文中,我们将继续讨论强引用的几种解决方案,以及强引用在Android开发中的应用。

强应用(强持有)

假设此时有两个界面A、B,从A push 到B界面,在B界面中有如下定时器代码。当从B pop回到A界面时,发现定时器没有停止,其方法是:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            //do something
        }
    }, 1000, 1000);
}

定时器强引用分析

  1. 该定时器为什么没有被释放?
  2. 该定时器是如何被强引用的?
  3. 该定时器应该如何被释放?

1. 该定时器为什么没有被释放?

该定时器没有被释放的原因是,该定时器被一个强引用所引用。该强引用是指向该定时器的变量timer。当该变量指向该定时器时,该定时器就不会被释放。

2. 该定时器是如何被强引用的?

该定时器被强引用的方式是,该定时器被一个静态变量所引用。静态变量是一个类级别的变量,它属于该类所有的对象。因此,当该定时器被一个静态变量所引用时,该定时器就属于该类所有的对象。这意味着,该定时器不会被释放,直到该类所有的对象都释放。

3. 该定时器应该如何被释放?

该定时器应该被释放的方式是,该定时器应该被一个弱引用所引用。弱引用是一个类级别的变量,它属于该类所有的对象。但是,当该定时器被一个弱引用所引用时,该定时器就不会被释放。这意味着,该定时器会直到该类所有的对象都释放,或者直到该弱引用被释放。

弱引用解决方案

我们可以在定时器中使用弱引用来解决这个问题。弱引用是一种特殊的引用类型,它不会阻止对象被回收。当一个对象被弱引用时,JVM只会将该对象加入到一个弱引用列表中。当JVM进行垃圾回收时,JVM会检查弱引用列表中的对象。如果一个对象没有被任何强引用或软引用所引用,那么该对象就会被回收。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    WeakReference<Timer> timer = new WeakReference<>(new Timer());
    timer.get().schedule(new TimerTask() {
        @Override
        public void run() {
            //do something
        }
    }, 1000, 1000);
}

当我们从B界面pop回到A界面时,定时器就会被回收。

软引用解决方案

我们也可以在定时器中使用软引用来解决这个问题。软引用是一种特殊的引用类型,它也不会阻止对象被回收。但是,当一个对象被软引用时,JVM只会将该对象加入到一个软引用列表中。当JVM进行垃圾回收时,JVM会检查软引用列表中的对象。如果一个对象没有被任何强引用或强引用所引用,那么该对象就会被回收。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    SoftReference<Timer> timer = new SoftReference<>(new Timer());
    timer.get().schedule(new TimerTask() {
        @Override
        public void run() {
            //do something
        }
    }, 1000, 1000);
}

当我们从B界面pop回到A界面时,定时器就会被回收。

强引用在Android开发中的应用

强引用在Android开发中的应用非常广泛。例如,我们可以使用强引用来防止Activity被回收。当一个Activity被强引用时,JVM不会回收该Activity,直到该Activity不再被使用。这可以确保Activity中的数据不会丢失。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final Activity activity = this;
    //create a strong reference to the activity
    StrongReference<Activity> strongReference = new StrongReference<>(activity);
}

结论

强引用是一种非常重要的引用类型。强引用可以防止对象被回收,直到该对象不再被使用。强引用在Android开发中的应用非常广泛。例如,我们可以使用强引用来防止Activity被回收。当一个Activity被强引用时,JVM不会回收该Activity,直到该Activity不再被使用。这可以确保Activity中的数据不会丢失。