目的:写给本身看的,不如其余大神全,之后慢慢修修改改java
一:如何判断数据是否垃圾数据算法
1.引用计数法服务器
当建立一个对象时,为此对象分配一个引用计数器。当有其余对象引用这个对象时,计数器就+1。当引用失效了,计数器-1。多线程
当一个对象的引用计数器=0时,此对象就能够被回收。并发
优势:原理简单,实现方便。框架
缺点:不能解决对象间循环引用问题,容易形成内存泄漏。优化
String a=hello线程
String b=weold设计
a=b对象
b=a
上面的例子中,这两个对象的引用计数器永远不为0,回收不掉,形成内存泄漏。
2.可达性分析法
这种算法的思想:判断一个对象和GC Root是否有相连的引用链,若是没有,则能够进行回收。这种算法解决了引用计数法的缺点(对象间循环引用问题)
2、如何回收垃圾(回收垃圾的方法)
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的到来
3、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记录了当前区域块中对象的引用关系。