jvm虚拟机

jvm的内存模型

1. 程序计数器

线程私有。
作用:可以看作是当前线程所执行的字节码文件的行号指示器。像分支、循环、跳转、异常处理等功能都需要依赖这个计数器完成

2. Jvm虚拟机栈

线程私有。
作用:虚拟机栈描述的是java方法的内存模型:每个方法被执行的时候会创建个栈帧,用于存放局部变量表、方法出口等信息。(局部变量表放的是基本数据类型、对象引用和returnAddress类型(指向一条字节码指令地址))。

3. 本地方法栈

线程私有。
作用:与java虚拟机栈相似,只是为本地方法服务而已。

4. java堆

线程共享。
作用:是java虚拟机管理内存最大的一块,用于存放对象实例,几乎所有的对象实例都在这里分配内存。

5. 方法区

线程共享。
作用:用于存储被虚拟机加载的类信息、常量、静态变量等数据。

GC垃圾回收

判断对象是否需要被回收

如何判断一个对象是否需要被回收(“死亡”)?
可达性分析法:通过GC Roots作为起点进行搜索,可以到达的对象是存活的,不可以到达的对象则是“死亡的”,需要被回收的。
Java中可以作为GC Roots的对象:
1.Jvm虚拟机栈中局部变量表中的引用的对象
2.本地方法中的JNI(java native interface)中引用的对象
3.方法区中常量引用的对象
4.方法区中静态属性引用的对象

垃圾回收算法

1.标记-清除算法
标记要回收的对象,然后清除
不足:标记和清除的效率不高;产生大量不连续的内存碎片,导致无法给大对象分配内存。
标记-清除
2.复制算法
复制算法的提出是为了克服句柄的开销和解决内存碎片问题。
将内存分成两块大小一样的区域,每次只使用一半的内存,当内存使用完的时候,就将还存活的对象复制到另一半内存中,然后将用过的那一半内存清理掉。
不足:只使用了一半的内存。
复制
3.标记-整理算法
在标记-清除的基础上,在清除的时候,将存活的对象向左端空闲的地方移动。
不足:开销比较大,但是解决了内存碎片问题
标记整理

4.分代算法
核心思想是根据对象的存活周期将内存分为不同的区域。一般堆区分为年轻代和年老代,在堆区之外还有一个永久代。年轻代每次都有量的对象需要被回收,年老代每次只有少量的对象需要回收;然后再根据不同的代的特点使用不同的回收算法。
分代算法

年轻代的回收算法
1.将新生的对象都放在年轻代中
2.年轻代的内存按照8:1:1分成Eden区和两个Suvivor(suvivor0,suvivor1)区,大部分的对象都在Eden区生成。回收的时候先将Eden区存活的对象放置在suvivor0区,然后再将Eden区清空。当suvivor0区存放满了的时候,则将Eden区和suvivor0区存活的对象放置在suvivor1区中,然后将其他两个区清空。此时survivor0区是空的,然后将survivor0区和survivor1区交换,即保持survivor1区为空, 如此往复。
3.当survivor1空间满了的时候,此时将存活的对象直接放入年老代,如果年老代也满了则会触发一次Full GC,也就是年轻代和年老代都发生垃圾回收
4.年轻代发生的GC也叫做Minor GC,MinorGC发生频率比较高(不一定等Eden区满了才触发)。

年老代的回收算法
1.在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。
2.内存比新生代也大很多(大概比例是1:2),当老年代内存满时触发Major GC即Full GC,Full GC发生频率比较低,老年代对象存活时间比较长,存活率标记高。

永久代的回收算法
用于存放静态文件,如Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate 等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。

垃圾收集器

垃圾收集器

1.Serial收集器
serial收集器
年轻代使用复制算法,年老代使用标记-整理算法
Serial收集器是一个单线程的垃圾收集器,当进行回收时会暂停所有其他工作线程,进行垃圾回收。(Client模式下的虚拟机中首选新生代收集器)
优点:(与其他单线程垃圾收集器相比)简单高效
缺点:停顿时间较长
2.ParNew收集器
ParNew收集器
年轻代使用复制算法,年老代使用标记-整理算法
ParNew收集器就是Serial收集器的多线程版本,在进行垃圾回收的时候也会暂停其他所有的工作线程。(Server模式下的虚拟机中首选新生代收集器)
CMS收集器
虚拟机第一款真正意义上工作线程和回收线程并发的收集器,停顿时间短,注重用户体验。
CMS垃圾收集器
标记-清除算法实现的垃圾收集器。运作相对前面收集器更加复杂,整个过程分成4部分:
1.初始标记: 暂停所有的其他线程,并记录下直接与root相连的对象,速度很快 ;
2.并发标记: 同时开启GC和用户线程,用一个闭包结构去记录可达对象。但在这个阶段结束,这个闭包结构并不能保证包含当前所有的可达对象。因为用户线程可能会不断的更新引用域,所以GC线程无法保证可达性分析的实时性。所以这个算法里会跟踪记录这些发生引用更新的地方。
3.重新标记: 重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记阶段时间短
4.并发清除: 开启用户线程,同时GC线程开始对为标记的区域做清扫。

缺点:对CPU资源敏感;
无法处理浮动垃圾;
它使用的“标记-清除”算法会导致收集结束时会有大量空间碎片产生
优点:并发收集、停顿时间短,用户体验好

G1收集器
G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征.
在这里插入图片描述
G1收集器大致分为以下几个步骤:
1.初始标记
2.并发标记
3.最终标记
4.筛选回收
优点:
1.并行与并发:G1能充分利用CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop-The-World停顿时间。部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让java程序继续执行。
2.分代收集:虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但是还是保留了分代的概念。
3.空间整合:与CMS的“标记–清理”算法不同,G1从整体来看是基于“标记整理”算法实现的收集器;从局部上来看是基于“复制”算法实现的。
4.可预测的停顿:这是G1相对于CMS的另一个大优势,降低停顿时间是G1 和 CMS 共同的关注点,但G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内

垃圾收集会被触发条件

(1)程序调用System.gc时可以触发;
(2)系统自身来决定GC触发的时机。
Minor GC ,Full GC 触发条件
Minor GC触发条件:
当Eden区满时,触发Minor GC。
Full GC触发条件:
(1)调用System.gc时,系统建议执行Full GC,但是不必然执行
(2)老年代空间不足
(3)方法区空间不足
(4)上一次GC之后Heap的各域分配策略动态变化;

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值