内存优化一

Java虚拟机

概念

Java虚拟机是一台"抽象的计算机",它拥有自己的处理器,堆栈,寄存器及相应的指令系统;Java虚拟机屏蔽了与具体操作系统相关的平台信息,使得Java程序只需要生成在该虚拟机上运行的目标代码,就可以以在多平台上运行;虽然叫Java虚拟机,但在它之上运行的语言不仅有Java,还有Kotlin,Groovy,Scala等都可以运行;

Java虚拟机执行流程

在这里插入图片描述

Java虚拟机运行时内存模型

线程私有:

  1. Java虚拟机栈
    • Java方法的调用状态,包括局部变量,参数,返回值等
  2. 本地方法栈
    • C stack
  3. 程序计数器
    • 保证程序能顺序执行
    • 唯一不会跑出OutOfMemoryError异常的

线程共享:

  1. 方法区
    • 被虚拟机加载的类结构信息
    • 运行时的常量池
    • 静态变量
  2. Java堆
    • 对象存在的地方
    • 垃圾回收主要战场

垃圾回收

引用类型

  1. 强引用
    当新建的对象为强引用时,垃圾回收器绝不会回收它。宁愿抛出OutOfMemoryError异常,让程序异常终止也不会回收;
  2. 软引用
    当新建的对象为软引用时,当内存不够时,回收器就会回收这些对象,如果回收后还是没有足够的内存,抛出OutOfMemoryError异常;
  3. 弱引用
    当新建的对象为弱引用时,垃圾回收器不会管当前内存是否足够,都会回收它的内存;
  4. 虚引用
    虚引用跟其它引用都不同,如果一个对象仅持有虚引用,在任何时候都可能被GC回收,只是当它被回收时会收到一个系统通知;

垃圾标记算法-引用计数算法

引用计数算法:每个对象都有一个引用计数器,当对象每被引用一次时就加1,引用失效时就减1。当计数器为0时则将该对象设置为可回收的“垃圾对象”。
这个算法有个问题:相互引用的问题,

垃圾标记算法-根搜索算法

在这里插入图片描述
从GC-ROOT往下搜索,搜索不到的对象就标记为可回收的“垃圾对象”,可以解决相互引用的问题。

垃圾收集算法-标记-清除算法

标记-清除算法:
顾名思义,用根搜索算法标记可回收的对象,之后将被标记为“垃圾”的对象进行回收。
在这里插入图片描述
这个算法会造成内存碎片,无法分配内存给大对象。

垃圾收集算法-复制算法

复制算法:
先把内存一分为二,每次只是用其中一个区域,垃圾收集时,将存活的对象全部拷贝到另外一个区域,然后对之前的区域进行全部回收;
在这里插入图片描述
这个可以解决内存碎片的问题,但是内存的利用率不高。在新生到的8:1:1的情况下最适合使用了。

垃圾收集算法-标记-压缩算法

标记-压缩算法:
在标记可回收的对象之后,将所有的存活的对下你给压缩到内存的一端,让他们排在一起,然后对边界以外的内存进行回收。
在这里插入图片描述
这个可以解决内存碎片的问题,但是内存的利用率也高。

垃圾收集算法-分代收集算法

分带收集算法:
Java堆中存在的对象生命周期有较大差别,大部分生命周期很短,有的很长,甚至与应用程序或者Java虚拟机的生命周期一样。分代算法就是根据对象的生命周期长短将对象放到不同的区域;

在这里插入图片描述
刚创建对象时,进入新生代的Eden区域,第一GC时把Eden存活的对象复制到FromSurvivor,第二次GC时, 将Eden和FromSurvivor存活的对象放到ToSurvivor区域;下一次GC时,将Eden和ToSurvivor中存活的对象放到FromSurvivor区域,如此反复,正适合用垃圾收集算法中的复制算法。当复制多次达到一定阈值之后,比如GC了15次了,某些对象还存活着,就会移到老年代了。

内存泄漏、溢出

内存泄漏:一个不再被程序使用的对象或者变量依旧存活在内存中无法被回收;

内存溢出:当程序申请内存时,没有足够的内存够程序使用;
比较小的内存泄漏并不会有太大的影响,但内存泄漏多了,占用的内存空间就更大,程序正常需要申请使用的内存则会相应减少;

内存抖动

内存抖动通常是指在短时间内发生了多次内存的分配和释放,主要原因则是短时间内频繁的创建对象,为了应对这种情况,虚拟机会频繁的触发GC操作,当GC进行时,其他线程会被挂起等待GC的完成,频繁GC,也就导致比如UI在绘制时会超过16ms一帧,导致画面卡顿等;

咋解决呢:Glide学习的时候学过复用池,当时是Bitmap的内存复用池,Bitmap回收之后,保留其内存,待下次使用的时候,可以从复用池中取内存,这样可以缓解内存抖动的问题;

内存分析工具

Mat:下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值