虚拟机
1.JVM
- Java Virtual Machine的简称。意为Java虚拟机。
2.内存区域划分
- 堆(空间最大):new的对象都在这,
- 方法区:类对象,静态成员
- 栈:JVM栈和本地方法栈,普通的局部变量
- 程序计数器:只放了一个内存地址
3.垃圾回收GC( garbage collection )
3.1GC
- 针对对象来进行回收
- 创建对象(申请内存)时机明确
- 销毁对象(回收内存)时机不明确
- 人工来保证导致会容易出现内存泄漏
- 大部分语言都有,java采取的办法:可达性分析,(另一种是引用计数,但是java不是用的这个)
- 堆(空间最大):主要回收堆,
- 方法区:偶尔回收
- 栈:不需要垃圾回收,会被自动释放,
- 程序计数器:不需要垃圾回收
3.1.1内存泄漏
- 产生原因:申请了内存没释放
- 带来的危害:可用内存持续变少,最终导致申请不到内存,程序崩溃
- 解决方案:GC能够一定程度的解决内存泄漏问题,一旦重启进程,泄露的内存也自然释放(例行重启)
3.2如何回收垃圾
- 垃圾:这个对象以后没人使用了(对于这个代码起不到贡献)
3.3引用计数
- 比如有一个对象,创建该对象的同时,给这个对象搭配一个计数器,每次有一个引用指向这个对象,计数器就+1,每次有一个引用被销毁,计数器-1当计数器为О的时候,这个对象就“没人引用了,自然也就是垃圾了"
- 引用计数是一个简单直观的衡量对象是否是垃圾的办法但是有缺陷
- 1.要求引用计数的++–操作,得是线程安全的(要加锁,加锁就会低效)
- 2.可能出现"循环引用"的问题~
3.4可达性分析
- Java里的对象都是通过引用来获取到的.一个引用能指向一个对象,一个对象里可能还包含若干个引用.这个引用关系,就构成了一个"图状结构"
3.5GC里面的四种算法
3.5.1.标记清除
- 先标记出垃圾再清除垃圾
- 标记的方式就是 可达性分析 。可达的对象刨除,剩下的就标记成垃圾。
- 清除的含义就是释放对象对应的内存空间
- 优点:简单,容易实现
- 缺点:可能会产生很多的内存碎片
3.5.2.复制算法
- 复制算法能够解决内存碎片问题~
- 分成两份,只用其中的一份~~
- 把不是垃圾的对象,复制到另外一半内存中,然后回收这整块内存~
- 复制算法,确实降低了内存碎片,但是把对象拷贝来拷贝去的,难道不低效??
低效取决于,每次垃圾回收的时候,你要复制的对象的多少~复制的越多,效率越低~ - 具体是回收的垃圾对象多,还是要保留的对象多,不同的场景不一样~~
- 优点:很好的解决了内存碎片问题
- 缺点:
- 1.有局限性,如果留下的对象多,可能会低效
- 2.内存利用率不高,要切出一半来~
3.5.3.标记整理
- 采取类似于"顺序表"删除中间元素的方式,搬运~
- 没有一劳永逸的办法~
需要具体场景采取不同的方法~ - 优点:没有内存碎片了,空间利用率也高了.
- 缺点:内存搬运操作比较频繁,效率不高
3.5.4.分代回收
- 分代回收,把回收的过程分成了几个场景,不同的场景下采取不同的回收方式
- 分代回收,主要就是基于一个经验规律:
如果一个对象存活的时间越久,就认为这个对象会继续更久的存活下去~~ - 如何衡量对象的"存活时间"
根据这个对象躲过的GC的轮次~(JVM 会周期性的进行可达性分析)给对象引入了“年龄",就是躲过的GC的轮次~