根据Java垃圾回收机制探讨内存优化

先看看Java程序运行时的内存模型


内存模型.png
  • 当你的Java字节码执行起来的时候,虚拟机就会它所管理的内存大致分成这五个部分,把你的代码分别扔到这五个框框里:
    • 方法区:用于存储类信息,常量静态变量等等这些
    • 本地方法栈:用于为本地方法的执行提供服务,pass
    • 栈:严格来说它叫虚拟机栈,是虚拟机执行Java方法的重要内存模型。同时存储局部变量,对象引用(有了这个,就能找到对象)等等。
    • 堆:存储对象实例的区域(比如 A a=new A(),那么 a这个引用就保存在栈中,而new A() 的这个对象就放在堆中)
    • 程序计数器:用来记录当前线程执行的字节码的地址,指示执行引擎执行代码。
       执行引擎:哎呀卧槽,刚才执行来哪一步来着?
       程序计数器:辣鸡。

你写的程序数据被分配到那五个区域之后。躲在暗处的那个饥渴难耐端的垃圾回收机制就马上跳出来了。

但是也不是每个区域他都去回收垃圾,不要以为只有人是势利的,其实GC程序也是很势利很现实的,它从来都只去那些容易收到垃圾的地方去收垃圾。也就是堆中。因为堆占据了Java运行时内存的大头........当然了,我是开玩笑的,实际上GC去哪里回收垃圾是规定好的。

  • “组织已经决定了,以后你就在堆里面回收垃圾了”(垃圾堆的历史来由我们就讲到这里。。。)

嗯,终于要到内存优化的地方了。前面已经讲到,Java会专注的在堆中回收垃圾,而堆中基本上之存放对象实例,所以内存回收的重点就是对象实例!!

那么,GC回收对象的准则什么呢?答案是GC Roots引用链

  • 通过这个引用链往下搜索,所有在这些链条上的,都是“活着的”对象,其余的就被回收了。

其实我知道,就算我解释那么多你也不太懂,没关系,我来画一画就好了,做事做全套嘛,

况且,我是专业的。


引用链.png
  • GC程序从栈顶开始一直找到栈底,寻找每个对象引用所对应的对象实例,然后在实例中寻找是否有指向其他对象的引用,若有,继续找(这一部分并没有画出,但是也是重点),没有,则回到栈中,继续往栈底搜索。
  • 当然,GC不止会在栈中寻找引用,还会在静态存储区(存储静态变量的地方,猜猜看对应着上述那个区域)中寻找引用,(因为有的堆中的对象在栈中没有引用,它的引用在静态存储区,类似于 static A a =new A() )

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

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

那么对应Android的内存优化的建议就很直观了,基本围绕了一个点:

  • Android中Activity等占据较大的内存空间对象,在不用的时候,一定保证当前对象的直接引用和间接引用全部被置为空。内存才能被释放。否则,就会有内存泄漏。

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值