为了活动小家电-Android 内存泄漏(一)

82 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

Android 内存类型

image.png

随机存取存储器 (Random Access Memory) - RAM

  • RAM 用于在应用程序运行时进行临时存储
  • 在这里,应用程序是指在前台运行的应用程序和在后台运行的应用程序。
  • 这是暂时的,因此当应用程序死机或设备重新启动时信息会丢失。

内存 - zRom

  • 作为 RAM 的一部分,未使用的资源被压缩并移动到保留区域以增加可用内存量。
  • 此压缩过程需要 CPU 上的更多工作,这会减慢设备运行速度。

存储器 - Storage

  • 您的数据、照片、视频、音乐、文档等应该在设备重启后仍然存在。
  • 示例包括 SharedPreference 、 SQLite 、 Realm 等。
  • Android 的存储空间各不相同,但今天的存储空间一般为 32GB、64GB、128GB 和 256GB,可以相当大。
  • 您还可以通过 microSD 卡等进一步扩展它。

内存管理过程由 Android Runtime (ART) 和之前的版本 Dalvik Virtual Machine 执行。

什么是内存泄漏

现在,我们需要知道为什么会发生内存泄漏,但在此之前,我们需要回想一下 JVM 是如何使用从操作系统接收到的内存的。

Android 使用 GC(Garbage Collector)来检索在堆区创建的对象。通过跟踪堆区域并从堆区域中检索不再使用的对象,留下内存区域。那么,如果你想一想,如果我们一直在堆中维护一个未使用的对象,GC 会认为该对象仍在使用中,而不是垃圾。这意味着无法从内存中释放对象,此时就会发生内存泄漏。如果不能一一删除这些数据,有时UI会变卡顿,app崩溃,就会出现OutOfMemory。

现在,让我们考虑一下,将它替换为 Android,因为我们以 Java 为例。有一个应用程序只有一个 TestActivity。

class TestActivity : AppCompatActivity(){

   override onCreate(savedStateInstance : Bundle?) {
       // 逻辑处理
   }
}

在这种情况下,由于没有创建其他线程,所以只存在主线程,即 UI 线程。那么,在MainThread的JVMStack区域中,应该有一个TestActivity类的值。TestActivity 的实现是在堆区域中,而不是值,具有实际对象值的按值调用类型,并且 JvmStack 将只有地址值,即 TestActivity 类的地址。

那么,其他各种Context或组成这些活动的其余对象也将在堆栈上(在 MainThread 堆栈中)

class SingletonTest(context : Context) {
   private var mContext = context 

   companion object{
       var instance : SingletonTest? = null
       
       fun getSingleton(context : Context) : SingletonTest {
            if(instance == null) {
                instance = SingletonTest(context)
            }
            return instance as SingletonTest
       }
   }
}

让我们像这样创建一个名为 SingletonTest 的类,以便我们可以接收单例形式的 Context。(这只是一个例子)

class TestActivity : AppCompatActivity(){

   override onCreate(savedStateInstance : Bundle?) {
       val singleton = SingletonTest.getSingleton(this)
   }
} 

这里隐藏了一个叫singleton的对象,从 TestActivity 调用 SingletonTest 的那一刻起,SingletonTest 就有了 TestActivity 的上下文,即使 TestActivity 死掉了,在 JVMStack 区域中引用的东西消失了,并且作为一个目标被包含在 GC 中,该实例仍然是被 TestActivity 引用。它被认为在使用,无法回收,这种情况会导致内存泄漏

为了活动小家电,下篇继续搞!