垃圾回收机制
2019-09-23 09:14:27来源:博客园 阅读 ()
垃圾回收机制
目的:写给自己看的,不如其他大神全,以后慢慢修修改改
一:如何判断数据是否垃圾数据
1.引用计数法
当创建一个对象时,为此对象分配一个引用计数器。当有其他对象引用这个对象时,计数器就+1。当引用失效了,计数器-1。
当一个对象的引用计数器=0时,此对象就可以被回收。
优点:原理简单,实现方便。
缺点:不能解决对象间循环引用问题,容易造成内存泄漏。
String a=hello
String b=weold
a=b
b=a
上面的例子中,这两个对象的引用计数器永远不为0,回收不掉,造成内存泄漏。
2.可达性分析法
这种算法的思想:判断一个对象和GC Root是否有相连的引用链,如果没有,则可以进行回收。这种算法解决了引用计数法的缺点(对象间循环引用问题)
二、如何回收垃圾(回收垃圾的方法)
1.Mark-Sweep 标记清除算法
缺点:回收之后会产生大量不连续的内存碎片,导致内存环境质量下降。印象是:当分配一个较大对象时,如果找不到连续的内存地址空间,则会提前出发一次GC(Full GC-全堆GC)
2.Copying算法 复制算法
优点:解决了Mark-Sweep的内存碎片问题
缺点:内存利用率较低,只有50%
根据研究,新生代的对象98%都是用完即扔。所以再划分内存空间大小时,按Eden(80%)和两块Survivor(10%)。每次是使用Eden和其中的一块Survivor。所以在这种优化下,新生代的内存利用率达到了90%。
3.Mark-Compact 标记整理算法
这种算法是基于标记清除算法做的改进。在进行垃圾清除过后进行碎片整理。
针对老生代的垃圾数据回收:①Mark-Sweep ②Mark-Compact
补充的概念:
新生代的GC称为:Minor GC 频率高
老生代的GC称为:Major(Full) GC 频率低
当发生Full GC时,是全堆GC,所以GC时间很长。
所以GC调优的目的是:尽量减少Full GC的出现或者延迟Full GC的到来
三、GC收集器
左图表示Java目前所支持的7种垃圾收集器。有连线表示可以配合使用。比如Serial和Serial Old可以一起使用。如果没有连线,就不能一起使用。
1.Serial 单线程收集器,特点是:垃圾回收时,会暂停所有的工作线程,而且停顿时间较长。这是java最早的收集器。
Serial的使用场景:可以回收桌面系统的垃圾
2.ParNew 多线程收集器。用于回收新生代的垃圾数据。因为是多线程收垃圾,所以停顿时间比Serial更短。
此外,ParNew还可以和CMS配合使用。CMS收集器停顿时间是最短的。
3.CMS(Concurrent Mark Sweep)
并发低停顿收集器。即回收垃圾时,CMS的间隔最短。
CMS的使用场景:对于服务器响应要求低延迟的场景使用,即注重服务器的低延迟相应速度。
比如HBase框架,后台在回收垃圾时,用的就是CMS。
CMS将垃圾回收分为4个过程:
1)初始标记 有停顿,仅是扫描对象引用链,所以停顿时间非常短。
2)并发标记
3)重新标记 有停顿,仅是扫描对象引用链,所以停顿时间非常短,作用是修正并发标记阶段的引用链变化
4)并发清除 垃圾清除阶段变为和用户并发处理机制,因为清除垃圾的时间是最长的,所以这样设计的目的可以极大的降低停顿的时间。并且清除垃圾的线程数可以调节。
优点:停顿时间最短,所以也称为并发停顿收集器
缺点:
①:CMS会产生浮动垃圾,这些浮动垃圾只能等到下一次GC时才能收掉。
②:垃圾收集线程和用户线程一起工作,共同抢用CPU时间片,所以可能会降低正常工作线程的执行效率。
③:CMS(Concurrent Mark Sweep)底层在回收垃圾时,用的时标记-清除算法,虽然快,但是会产生内存碎片。所以需要定期做碎片整理。
4.Parallel 吞吐量优先收集器
这类收集器并不关注回收的停顿长短,而是关注回收的吞吐量。
5.G1GC
G1GC舍弃了传统GC收集器的特点,不再将整个heap分为新生代和老生代,而是再heap创建一个一个的区域块(大小可以设置,最小是1MB,最大是32MB)进行处理。每一个区域块内部不进行新旧分区。而是整体被标记为Eden/Survivor/Old。
优点:
1.内存利用率非常高,利用了整个Heap的内存空间。而之前的传统GC收集器可能出现的情况:新生代内存紧张,老生代内存空余,这就是一种资源浪费的体现。
所以对一个服务器来说,内存越大,G1GC优势越明显。
2.对于GC,有两种,分别是Minor GC和Full GC。如果使用G1,触发Full GC的条件是:在整个Heap中找不到全空区域时才会发生Full GC。
所以,使用G1,发生Full GC的频次更低。
3.G1 GC引入了RememberSet的概念,避免在整个堆中扫描引用链,使得每个区域块的GC更快、更加独立。RememberSet记录了当前区域块中对象的引用关系。
原文链接:https://www.cnblogs.com/hi-zhixian/p/11564908.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:java this的作用
下一篇:Spring -- AOP
- 数据源管理 | Kafka集群环境搭建,消息存储机制详解 2020-06-11
- 深入浅出 Java 类加载机制! 2020-06-05
- Java连载120-反射机制获取构造方法和父类、父接口 2020-06-05
- CGLIB动态代理机制,各个方面都有写到 2020-06-04
- Java 从入门到精通-反射机制 2020-06-03
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash