资讯专栏INFORMATION COLUMN

jvm体系结构和gc调优(一)

wupengyu / 603人阅读

摘要:做好的优化能大大提升系统的性能体系结构概览大致流程如图编译好的文件通过类加载器从物理结构转换成运行时数据区结构。后面再写一篇关于调优的

什么是jvm

jvm是java虚拟机的缩写。所有的java程序都是在jvm上运行的。做好jvm的优化能大大提升系统的性能

jvm体系结构概览

大致流程如图:编译好的class文件通过类加载器从物理结构转换成运行时数据区结构。再通过jvm内置执行引擎和本地方法的调用实现 ps:本地方法就是带有native关键字的方法

其中方法区和堆是最重要的两块区域(这里是以java7为参照。java8没有方法区)
因为这两块是gc算法作用的最主要区域

gc算法

如果需要收集垃圾,则必须先找到垃圾。

1.引用计数法

解释:每个对象都带有一个引用计数器,当其他声明的变量指向这个对象时候,计数器就+1,当指向消逝时候,就将计数器-1.垃圾回收只回收计数为0的对象。
缺点:无法回收循环引用的情况,比如A引用了B,B引用了C,C引用了A. 这种GC算法还需要编译器进行配合,对对象引用进行计数,需要额外生成代码。

2.可达性分析

解释:设立若干个根对象,当一个对象不能通过任何根对象引用达到,那么这个对象在finalize中有一次可以请求“重生”机会,或者直接忽略finalize,选择直接死亡。

找到垃圾后,开始垃圾收集

标记清除算法

简单解释下:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。它的主要缺点有两个:一个是效率问题,标记和清除过程的效率都不高;另外一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致,当程序在以后的运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作

这是最基本的gc算法,后续的gc算法都是根据这种思路来改进的

标记压缩算法

标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存

复制算法

将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

分代收集算法

把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”或“标记-整理”算法来进行回收。
这里总共会有三种gc


不同的gc使用不同的gc算法

注:默认新生代eden区和survivor区比例为8:1:1

火车算法

最先进的g1收集器使用的gc算法,相对于分代收集,它的分区处理更彻底

在火车算法中,内存被分为块,多个块组成一个集合。为了形象化,一节车厢代表一个块,一列火车代表一个集合,火车与车箱都按创建顺序标号,每个车厢大小相等,但每个火车包含的车厢数不一定相等;每节车箱有一个被记忆集合,而每辆火车的记忆集合是它所有车厢记忆集合的总和;算法在执行时,要么收集最小数字车厢,要么收集最小数字火车。如果整节火车都是垃圾,就收集最小数字火车。

现有该场景

内存分为四块。 其中F,C,D,E是垃圾。G,A,B存活对象
首先扫描第一块内存。发现G是存活对象,F是垃圾。利用记忆集合将G的应用存到最后一块内存
回收第一块内存

如果再次发生gc,则同样扫描第二块内存。发现A,B都是存活对象,都移到最后一块内存。回收第二块内存

因为火车算法是将一块内存的对象移到另一块内存上并清除原来的内存。很像复制算法。
所以火车算法就被称为局部复制,外部标记清理

火车算法的问题

如果要保存一个比内存块大的对象怎么办

如果两个对象在不同内存块相互调用怎么办

垃圾回收器 垃圾收集器一览

术语

新生代垃圾收集器

serial (串行收集器) 特点

串行,stop the world

适用场景

单cpu,新生代内存小,对暂停时间要求不高的应用
是client和32位windows的默认垃圾收集器

对象分配到old区的情况

对象大于eden区

大对象直接分到old区

晋升规则

经历多次gc后仍存活的对象

to survivor区装不下直接晋升

parallel scanvenge收集器 特点

并行,stop the world
并行线程数默认值:cpu <= 8 则 线程数=cpu数 cpu>8 则(3+cpu*5)/8
可自定义线程数 :

适用场景

多cpu,对暂停时间较短的应用
是server和2核cpu,2g内存的默认选择

对象分配到old区的情况

在eden区分配失败,且对象大于eden的一半

大对象直接分到old区

晋升规则

经历多次gc后仍存活的对象

to survivor区装不下直接晋升

parnew 特点

并行,stop the world
serial的多线程版
可搭配cms
不能搭配parllel old

适用场景

多cpu,对暂停时间较短的应用
是server和2核cpu,2g内存的默认选择

对象分配到old区的情况

对象大于eden区

大对象直接分到old区

晋升规则

经历多次gc后仍存活的对象

to survivor区装不下直接晋升

老年代垃圾收集器

serial old 特点

串行,stop the world ,标记整理算法,清除时间长

适用场景

是client和32位windows的默认垃圾收集器

parallel old 特点

串行,stop the world ,标记整理算法

适用场景

是server和2核cpu,2g内存的默认选择

cms 特点

并行,并发,标记清理算法
默认并发线程数:(新生代并行线程数+3)/4

适用场景

暂停时间短,很适用于追求高响应速度的互联网引用

执行步骤

缺点

和应用抢占cpu

gc耗时长

浮动垃圾

内存碎片

第一篇先到这儿了。先消化一下。后面再写一篇关于调优的

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69520.html

相关文章

  • JVM体系结构GC调优(二)

    摘要:在设计堆的大小时。设计为比更大的数前提是内存允许。这样既可以降低堆调整的频率,还可以提高系统的负载能力新生代调优大小增大区。因为时间跟存活对象成正比新生代调优晋升尽可能让对象停留在中。 jvm支持的垃圾收集器组合 showImg(https://segmentfault.com/img/bVbbcTv?w=1101&h=351); 组合选择的标准 吞吐量=应用运行时间/总时间 关...

    DirtyMind 评论0 收藏0
  • 面试官问我JVM调优,我忍不住了!

    面试官:今天要不来聊聊JVM调优相关的吧?面试官:你曾经在生产环境下有过调优JVM的经历吗?候选者:没有面试官:...候选者:嗯...是这样的,我们一般优化系统的思路是这样的候选者:1. 一般来说关系型数据库是先到瓶颈,首先排查是否为数据库的问题候选者:(这个过程中就需要评估自己建的索引是否合理、是否需要引入分布式缓存、是否需要分库分表等等)候选者:2. 然后,我们会考虑是否需要扩容(横向和纵向都...

    不知名网友 评论0 收藏0
  • JVM调优之经验

    摘要:内存设置现在线上业务系统基本物理内存都是够用的,不过物尽其用,我们调优就是争取让每空间都发挥出最大的作用。区总内存减去一个区的大小不宜过大,否则可能把物理内存耗光。 在生产系统中,高吞吐和低延迟一直都是JVM调优的最终目标,但这两者恰恰又是相悖的,鱼和熊掌不可兼得,所以在调优之前要清楚舍谁而取谁。一般计算任务和组件服务会偏向高吞吐,而web展示则偏向低延迟才会带来更好的用户体验。 本文...

    worldligang 评论0 收藏0
  • [译]GC专家系列3-GC调优

    摘要:原文链接本篇是专家系列的第三篇。但是,请记住调优是不得已时的选择。缩短耗时的单次执行与相比,耗时有较明显的增加。创建文件过程中,进程会中断,因此不要在正常运行时系统上做此操作。因此校验结果并根据具体的服务需要,决定是否要进行调优。 原文链接:http://www.cubrid.org/blog/dev-platform/how-to-tune-java-garbage-collecti...

    leap_frog 评论0 收藏0
  • jvm调优

    摘要:一内存调优主要的目的是减小的频率和的次数。调优工具之主要用来输出中运行的进程状态信息。调优工具之和用来查看堆内存使用状况,一般结合使用。 一、jvm内存调优 主要的...

    snowLu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<