博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解Java虚拟机(二)
阅读量:6892 次
发布时间:2019-06-27

本文共 2098 字,大约阅读时间需要 6 分钟。

hot3.png

第三章  垃圾收集器与内存分配策略

    目前内存的动态分配与内存回收技术已经相当成熟和自动化,为什么还需要去了解GC和内存分配?:当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就需要对这些“自动化”的计划实施必要的监控和调节;

    第二章介绍了Java内存运行时区域的各个部分,其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭;这几个区域的内存分配和回收都具备确定性,随着方法结束或者线程结束时,内存自然就跟随着回收了;Java堆 和 方法区则不一样,这部分内存的分配和回收都是动态的;

    引用计数法:无法解决循环引用问题;   可达性分析法:通过一系列称为GC Roots的对象作为起始点,向下搜索形成引用链,当一个对象到GC Roots没有任何引用链相连,则证明此对象是不可用的;                   在Java语言中,可以作为GC Roots的对象有下面几种: 1. 虚拟机栈(栈帧中的本地变量表)中引用的对象    2. 方法区中类静态属性引用的对象    3. 方法区中常量引用的对象   4. 本地方法栈中JNI(即一般说的Native方法)所引用的对象

    引用(只要存在强引用,垃圾收集器永远不会回收掉被引用的对象)、引用(对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常)、引用(被弱引用关联的对象只能生存到下一次垃圾收集发生之前)、引用;        两次标记过程: 

    回收方法区(部分虚拟机的永久代):回收 废弃常量无用的类;  类需要满足下面3个条件才能算是“无用的类”: 1. Java堆中不存在该类的任何实例  2. 加载该类的ClassLoader已经被回收  3. 该类对应的java.lang.Class 对象没有在任何地方被引用, 无法在任何地方通过反射访问该类的方法;  类并不是和对象一样,不使用了就必然会回收。  在大量使用反射、动态代理、CGLib等ByteCode框架、动态生成JSP以及OSGi这类频繁自定义ClassLoader的场景都需要虚拟机具备类卸载的功能,以保证永久代不会溢出;

    垃圾收集算法标记-清除算法: 先标记,后清除;效率不高,会产生内存碎片;  复制算法: 将内存按容量划分为大小相等的两块,每次使用其中一块,当一块内存用完,就将还存活着的对象复制到另一块上面,然后再把已经使用过的内存空间一次清理掉;缺点:将内存缩小为原来一半,代价太高;   现代商业虚拟机都采用复制算法来回收新生代;  Eden 、From Survivor 、To Suvivor(8:1:1);  标记-整理算法: 对象存活率较高的时候复制收集算法要执行较多的复制操作,效率较低,还需要额外的空间进行分配担保;所以在老年代使用“标记-整理算法”,先标记,再把存活的对象都向一段移动,再直接清理掉边界以外的内存;   分代收集算法: 在新生代中,每次垃圾收集都发现有大批对象死去,少量存活,选用复制算法;老年代对象存活率高,没有额外空间对它进行分配担保,就必须使用“标记-清除”或“标记-整理”算法来进行回收;

    GC停顿:  

   

垃圾收集器长时间停顿,表现在 Web 页面上可能是页面响应码 500 之类的服务器错误问题,如果是个支付过程可能会导致支付失败,将造成公司的直接经济损失。两个原因:

  • 在 CMS 启动过程中,新生代提升速度过快,老年代收集速度赶不上新生代提升速度
  • 在 CMS 启动过程中,老年代碎片化严重,无法容纳新生代提升上来的大对象

发送这种情况,应用线程将会全部停止(相当于网站这段时间无法响应用户请求),进行压缩式垃圾收集(回退到 Serial Old 算法)

新生代提升过快问题:(1)如果频率太快的话,说明空间不足,首先可以尝试调大新生代空间和晋升阈值。(2)如果内存有限,可以设置 CMS 垃圾收集在老年代占比达到多少时启动来减少问题发生频率(越早启动问题发生频率越低,但是会降低吞吐量,具体得多调整几次找到平衡点),参数如下:如果没有第二个参数,会随着 JVM 动态调节 CMS 启动时间

-XX:CMSInitiatingOccupancyFraction=68 (默认是 68)

-XX:+UseCMSInitiatingOccupancyOnly

老年代碎片严重问题:(1)如果频率太快或者 Full GC 后空间释放不多的话,说明空间不足,首先可以尝试调大老年代空间(2)如果内存不足,可以设置进行 n 次 CMS 后进行一次压缩式 Full GC,参数如下:

-XX:+UseCMSCompactAtFullCollection:允许在 Full GC 时,启用压缩式 GC

-XX:CMSFullGCBeforeCompaction=n     在进行 n 次,CMS 后,进行一次压缩的 Full GC,用以减少 CMS 产生的碎片    

     

    安全点:

 

 

 

 

 

 

    

 

转载于:https://my.oschina.net/zfscofield/blog/1613397

你可能感兴趣的文章
大力发展金融创新,GTQ FIN致力于发展创新型衍生品交易平台
查看>>
安装vue-cli 3.0和注意事项
查看>>
【Vue.js 牛刀小试】:第十一章 - Vue 中 ref 的使用
查看>>
JSX
查看>>
LeetCode 之 JavaScript 解答第239题 —— 滑动窗口最大值(Sliding Window Maximum)
查看>>
一个项目带你走进产品经理的世界(2)需求分析
查看>>
css经典布局——圣杯布局
查看>>
Java基础系列五
查看>>
css3常用属性总结(1)
查看>>
SQLServer之创建索引视图
查看>>
面试集锦(六)数据结构(2)
查看>>
VimWiki的一些技巧
查看>>
GMQT全球通用积分重磅推出
查看>>
spring cloud构建互联网分布式微服务云平台-路由网关(zuul)
查看>>
Parasoft dotTEST(10.4.1)更新亮点——在.NET应用程序中构建安全性
查看>>
混沌工程究竟用来解决什么问题?
查看>>
如何写好一片文章
查看>>
vue项目前后端实现
查看>>
BCH升级日期将至,社区组织开始为11月“硬分叉”做准备
查看>>
2018最新版直播系统源码:功能和步骤详解
查看>>