JVM3
- JVM3 推荐度:
- 相关推荐
JVM3
一、垃圾回收概述
1、垃圾对象:运行程序中没有任何指针指向的对象
2、垃圾回收区域: 方法区+堆空间
频繁回收Young区
较少回收old区
基本不动Perm区(或元空间)
3、垃圾回收的两个阶段
(1)标记阶段
引用计数算法
可达性分析算法
(2)清除阶段
标记-清除算法
标记-复制算法
标记-压缩算法
4、运行时数据区垃圾回收情况
(1)方法区------------有GC+OOM(outofmemory内存溢出,堆溢出)
(2)堆----------------有GC+OOM
(3)程序计数器-------都没有
(4)本地方法栈-------没有GC,有SOF(stack over flow栈溢出)
(5)虚拟机栈------------没有GC,有SOF
5、内存溢出(OOM)
(1)定义
没有空闲的内存,且垃圾回收器也无法提供更多的内存
(2)产生原因
- JVM的堆内存设置不够
内存溢出一般指堆内存,一般也会由内存泄露导致内存不足
- 创建了大量大对象,且存在被引用,长时间不能被GC收集
(3)内存溢出是引发程序崩溃的原因之一
6、内存泄露(Memory Leak)
(1)定义
该对象不会再被程序用到了,但GC又不能回收他们
(2)产生原因
由于编码的习惯或疏忽,导致对象的声明周期很长,导致OOM---宽泛意义上内存泄露,但是存成了
如:局部变量可以解决的,结果声明成全局变量或静态变量;有些对象没必要存到session区域,成会话级别的对象
(3)内存泄露可能导致OOM,在超出内存空间时,才会导致
7、STM--stop the world
(1)定义
只GC时间发生过程中,会产生应用程序的停顿
停顿产生时,整个应用程序线程都会被暂停,没有任何响应。
(2)发生STW的场景
可达性分析算法中,枚举根节点会导致所有java执行线程停顿
(3)STW一般是由JVM在后台自动发起或自动完成的
手动调用System.gc()也会导致SWT的发生
8、Systen.gc()
(1)触发Full GC
- 通过调用System.gc()或Runtime.getRuntime.gc()显示触发Full GC
- Full GC:整个堆,对老年代和新生代同时进行回收,尝试释放被丢弃的对象所占用的内存
(2)Systen.gc()可以触发Full GC进行垃圾回收,但是不确定是否马上执行gc
(3)一般是自动垃圾回收,很少手动调用Systen.gc()
9、引用--强软弱虚 java.lang.ref
- 强引用(Strong Reference)---不回收
(1)特点:
无论任何情况下,只要强引用关系还存在,垃圾回收器就永远不会回收被引用的对象
如,new的对象
(2)强引用类型对象回收条件:
没有引用关系或显示将引用复制为null
(3)强引用是造成java内存泄露的主要原因之一
- 软引用(Soft Reference)---内存不足即回收
(1)特点:
在系统将要发生内存溢出时,将存在此类引用的对象二次回收掉
(一次回收将不可达对象的回收)
(2)软引用对象是非必需的对象
- 弱引用(Weak Reference)---发现即回收
(1)特点:
只被该引用关联的对象只能存活到下一次垃圾收集之前,无论引用是否存在
(2)软引用对象是非必需的对象
(3)可以用来保存可有可无的缓存数据
内存缓存(一级)----本地缓存(二级)---网络缓存(三级)
(4)WeakHashMap---利用的弱引用
可以在内存不足时,及时回收数据,避免用强引用导致OOM发生
HashMap---利用强引用
- 虚引用(Phantom Reference)--对象回收跟踪
(1)特点:
一个对象是否有虚引用,完全不会影响一个对象的生存时间
(2)唯一目的
在这个对象被收集器回收时接收到一个系统通知,相当于没有引用,设置个回收提醒而已
[注]引用关系还在情况下,GC机制对带有以上不同引用的对象处理
二、垃圾标记阶段
目的:区分出内存中哪些是存活对象,哪些是死亡对象
当一个对象已经不在被任何的存活对象继续引用时,就是垃圾对象
(一)引用计数法(java中不用)
1、每个对象保存一个整型的引用计数器属性,用于记录对象被引用情况
2、当一个对象引用该对象,引用计数器就+1,当引用失效时,引用计数器就-1
只要对象的引用计数器的值为0,则表示对象可进行回收
3、缺点
(1)需要单独的字段存储计数器,增加空间开销
(2)经常更新计数器,增加增加开销
(3)无法处理循环引用情况
(二)可达性分析(根搜索算法,追踪性垃圾收集)
1、可以解决循环引用问题
2、使用条件
保证数据一致性
2、原理:
以跟对象集合为起始点(GC Roots),
按从上至下的方式搜索被根对象集合所连接的对象是否可达
可达---非垃圾;不可达---垃圾
3、根对象集合(GC Roots )
一组必须活跃的引用,主要有以下几类元素:
(1)Java虚拟机栈中引用的对象 :局部变量
(2)本地方法栈中引用的对象:引用类型静态变量,类变量
(3)方法区中引用的常量对象:字符串常量池里的引用
(4)被同步锁synchronized持有的对象
(5)分代收集和局部回收
4、MAT---可以查询GC Root
一款强大的Java堆内存分析器
5、对象的状态
可触及----不是垃圾
可复活---是垃圾,但是可以通过调用重写的finalize()复活
不可触及--是垃圾,且已经调用了finalize(),但这个方法只能被调用一次,因此不可再复活
三、垃圾回收阶段
(一)标记-清除算法(Mark-Sweep)
1、原理
(1)当堆内存中的有效内存空间被耗尽时,就会停止整个程序(stop the world)
(2)标记非垃圾对象:Cllector从引用根节点(GC Root)开始遍历,标记所有被引用的对象,在对象header中记录为可达对象
(3)清除垃圾对象:Cllector遍历堆内存中所有对象,header中没有被标记为可达对象的,则被回收清除
2、缺点:
(1)需要停止整个应用程序,用户体验差
(2)清理出的空闲内存不连续,产生内存碎片----需要维护空闲列表
(3)遍历效率不算高,需要遍历两次
3、清除
清除不是真的置空,而是将需要清除的对象地址保存在空闲的地址列表中
如果有新对象需要加载时,先判断垃圾空闲位置空间是否够,够就用新对象覆盖原来数据
(二)复制算法
1、原理:
(1)将内存分为两块,每次只使用其中一块
(2)垃圾回收时,将正则使用的内存中存活对象复制到未被使用的内存块中,之后清除当前正在使用的内存块中所有对象,
循环交换,完成垃圾回收
2、优缺点:
优:没有标记和清除过程,简单高效
空间连续,不会出现碎片问题,可采用指针碰撞方式分配对象
缺:需要两倍的内存空间
只适合垃圾对象比较多的场景,这样复制算法复制的对象数量不会太大---适合在新生代中使用,不适合在老年代中使用
(三)标记-压缩算法(整理,mark-compact)
1、原理
(1)从根节点标记所有被引用的对象
(2)将所有存活的对象整理到内存的一端,按顺序排放
(3)清除所有未标记的垃圾对象
2、优缺点
优:解决了上两个算法的问题:对碎片化空间进行了整理,消除了复制算法的内存减半的代价
缺点:效率偏低,移动对象的同时,引用该对象的其他对象要调整引用的地址
移动过程中需要全程暂停用户程序 STW
四、回收算法的应用
(一)分代收集算法
1、新生代---回收频繁---复制算法
2、老年代---回收不频繁---标记-清除或标记-整理混合实现
(二)增量收集算法---降低延迟(GC产生的停顿时间)
1、作用
因为一次性处理所有垃圾时,会停掉所有程序,这造成系统长时间的停顿
解决STM(stop the world)状态下的时间过长问题,即延迟时间较长
2、基本思想:
每次垃圾收集线程只收集一小片区域的内存空间,接着切换到应用程序线程
让垃圾收集线程和应用程序线程交替执行,直至垃圾收集完成
3、使用的GC算法
标记-清除和复制算法
通过对线程间冲突的妥善处理,允许垃圾收集线程以分阶段的方式完成标记、清理或复制工作
4、缺点:
线程切换和上下文切换的消耗,使垃圾回收的总体成本上升,造成系统吞吐量下降
(三)分区算法-----降低延迟(GC产生的停顿时间)
1、作用
主要解决GC所需要的停顿时间问题(STW)---降低延迟
2、基本思想
(1)将一块大的内存区域分割成多个小块
(2)设置目标停顿时间,根据这个时间每次合理地回收若干个小区间(region)
3、分区
将一整块堆空间分成若干个region,不同的region盛放不同对象,如某几个region放同一类对象
Eden---边缘区数据
Survivor---新生代数据
Old------老年代数据
Humongous----大对象
4、回收过程:
(1)每次new对象时,会先放在eden区
(2)当年轻代的Eden区快满时,出发Yong GC,发生STW标记可达对象,是垃圾---清除
(3)将其中存活的对象复制移动到s0或s1区,谁空放在谁那里(to区),
然后遍历标记另一survivor区,垃圾清除,存活则移动到to区(复制算法 )
(4)遍历时,form区的对象被回收超过15次依旧存活时(年龄计数器值=15),就转移到老年区
[注]
- s0和s1可分为from区和to区
谁空谁是to区,循环调换
- Young GC只有当eden区满的时候才会触发,survivor区满不会触发
- 老年代:年龄值15
老年代空间不足时先触发Major GC----还不足OOM
5、不同GC触发条件
<1>Young GC (Minor GC)---年轻代中eden区满【年轻代回收】
<2>Old GC (Major GC)---老年代区满【老年代回收】
<3>Full GC ---年轻代中eden区满【整个堆回收,包括年轻代和老年代】
6、触发Full GC条件
- 调用System.gc( )
- 老年代空间不足
- 方法区空间不足
- Minor GC后,进入老年代的平均大小>老年代可用内存
- 亚马逊迫于微软竞争压力调低云服务价格
- 栅栏密码(The Rail
- MDG convenience API示例代码
- 《Microsoft SQL Server入门教程》第03篇 示例数据库和示例表
- 如何查阅NLP资料转自https:blog.csdn.netqq
- 数据库主键到底是用自增长(INT)好还是UUID好?
- 在3D游戏中显示网页
- CStdioFile类学习
- nfs服务器安装
- 几种均衡负载算法
- 负载均衡负载场景和解决方案
- 请描述你对测试的了解, 内容可以涉及测试流程, 测试类型, 测试方法, 测试工具等。
- 美团招聘计算机视觉算法岗实习生
- Android与MVC设计模式
- PTA刷题技巧
- janus videoroom之媒体录制
- Hadoop安装(二)
- Java并发Future
- QuickRedis 是一款 Redis 可视化管理工具
- Ubuntu的常用命令总结——简单版