从Java垃圾回收机制窥探内存优化(加强版)

前言

其实这篇文章几个月以前已经发布到简书博客里了,可是文章发布以后,有人反馈了一些问题,而我对于这篇文章也有删改增补的想法,因此这篇文章会是原文的简洁加强版python

回答一个疑问

这篇文章讲的是Java的JVM的垃圾回收机制,可是Android使用的虚拟机是Dalvik或者ART,那么下面讲的垃圾回收机制是否适用于Android呢?android

答案是,Yes,是能够类比的。算法

增补
文章末尾有人提出了质疑: JVM 的内存模型和 Android 虚拟机是区别的?网络

答案:是的,Android基于寄存器,jvm基于堆栈,本文其实避免了这样的探讨,那是由于在逻辑上它们其实没有太大区别,Android做为移动操做系统基于寄存器,能够极大提升它的访存速度,从而提升它的程序运行速度,堆栈访存就慢些。这是最大的区别,在这里作出说明。多线程

其余的问题我也在评论里作出了回应,有任何问题均可以在下面探讨,若是本文有重大漏洞,我会卸载勘误
一栏中,你们能够关注一下。jvm


开始

做为Android工程师,我看过不少关于Android内存泄漏的相关优化的文章,其中大部分都是告诉你该怎么作,作哪些,列一些具体的措施。不多解释为何要这么作,即便解释,也只是一笔带过。post

今天,我就之内存回收为突破口,向你们解释从底层到上层,是如何配合完成内存回收的。咱们就从Java程序运行时的内存区域开始吧。优化

运行时内存区域,指的是当你的程序被JVM加载进来执行的时候,内存是怎么分配的。spa

下面,就是Java程序运行时的内存模型操作系统

  • 如上图所示,当你的Java字节码执行起来的时候,虚拟机就会它所管理的内存大体分红这五个部分,把你的代码,产生的对象等等分别扔到这五个框框里:
    • 方法区:用于存储类信息,常量,静态变量,编译后的代码等等这些
    • 本地方法栈:用于为本地方法的执行提供服务(能够不了解)
    • 虚拟机栈:是虚拟机执行Java方法的重要内存模型。内部有一个局部变量表,这个表存储了对象引用(这个局部变量表常被咱们成为栈)。
    • 堆:存储对象实例的区域(好比 A a=new A(),那么 a这个引用就保存在上面的局部变量表中,而new A() 的这个对象就放在堆中
    • 程序计数器:用来记录当前线程执行的字节码的地址,指示执行引擎执行代码。
      执行引擎:哎呀卧槽,刚才执行到哪一步来着?
       程序计数器:傻逼。复制代码

其实上面那五个区域,和这篇文章关系最紧密的时虚拟机栈中的局部变量表(也就是咱们常说的栈),栈中主要保存了对象的引用,堆中保存了实际的对象,所以,实际上堆占了整个程序运行内存的大头,所以,内存回收就发生在堆中。

当程序运行时,而后躲在暗处的那个饥渴难耐端的垃圾回收机制(GC)就立刻跳出来了。虎视眈眈的盯着堆中的对象,专门找那些“落单”的对象....

那么,GC是怎么知道哪一个对象“落单”了呢,答案是GC Roots引用链。

  • 经过这个引用链往下搜索,全部在这些链条上的对象都拿到了免死金牌,而其他就是落单的,它们随后就会被GC回收。

关于GC引用链不管怎么说,都很难想象,那不要紧,我来画一画就行了。

  • GC程序从栈顶开始一直找到栈底,寻找每一个对象引用所对应的对象实例,而后在实例中寻找是否有指向其余对象的引用,如有,继续找(这一部分并无画出,可是也是重点),没有,则回到栈中,继续往栈底搜索。
  • 固然,GC不止会在栈中寻找引用,还会在静态存储区(存储静态变量的信息存储在方法区)中寻找引用,(由于有的堆中的对象在栈中没有引用,它的引用在静态存储区,相似于 static A a =new A() )

当那些待回收的对象被标记以后,GC就会开始回收对象释放内存。GC的回收算法有不少种,通常虚拟机配合多种内存回收算法来实现内存的高效回收,可是这些和咱们其实关系不大,所以能够略过。

好了,咱们终于把Java内存回收的机理讲完了,那么内存优化背后的机理也基本被咱们扒开了:

  • 再也不使用对象时,将引用置空,那么GC顺着栈或者静态存储区中的引用就找不到堆中对应的对象,那么这个对应的对象就会被回收。
  • 尽可能不要在生命周期较长(程序执行期间可能都不会被收回)的对象实例中引用其余的没必要要的占内存较大的对象实例

不少Android优化场景,基本围绕了一个点:

  • Android中Activity,context,bitmap等占据较大的内存空间对象,在不用的时候,必定保证当前对象的直接引用和间接引用所有被置为空。内存才能被释放。(重点注意多线程和网络请求这种不可控的场景)

因此Java内存优化一个最根本的准则,就是努力使你的程序适配Java的GC机制

后记

最近下定决心要涉足新领域,所以给本身定下目标,从这一篇开始,要系统的概括本身所学的知识技术以及积攒的经验,以文章的方式产出。内容主要以Java+Android相关为主,以JS+React-native次之,而后是一些基于python的有意思的项目(是大学里写的,会从新整理)。

你们放心,个人文章会保证一向的简单友好,至少同一个层次的知识,个人文章能比别人更加友好,我有这样的信心。

回到这篇文章自己,其实在从新整理的时候,我已经发现最近掘金上已经有人把Android优化整理了一个系列文章,我以为写的很不错,在这里也能够推荐给你们@anly_jun: android优化系列

固然,若是你比较欣赏个人文章风格,欢迎关注我,我会在保证文章质量的前提下,提升写做速度的。

共勉

勘误

暂无

参考

《深刻理解Java虚拟机》

相关文章
相关标签/搜索