import java.util.*;
import java.math.*;
/**
* 垃圾回收机制介绍,垃圾回收算法,通用分带垃圾回收机制
* @author 110
*
*/
/*
* 1:引用技术法
* 堆中每个对象都有一个引用计数。被引用一次,计数加1,被引用变量值变为null,则计数减1,知道计数为0,
* 则表示变成无用对象。优点是算法鸡蛋,缺点是“循环引用的无用对象”无法识别。
* 循环引用示例
* public class Student{
* String name;
* Student friend;
* public static void main(String[] args){
* Student s1 = new Student();
* Student s2 = new Student();
* s1.friend=s2;
* s2.friend=s1;
* s1=null;
* s2=null;
* }
* }
* s1和s2互相引用对方,导致他们引用计数不为0,但是实际已经无用,但无法被识别。
* 2:引用可达法(根据搜索法)
* 程序把所有的引用关系看作一张图,从一个节点GC ROOT开始,寻找对应的引用节点,找到这个节点以后,继续寻找
* 这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。
*/
/*通用分带垃圾回收机制:
* 分代垃圾回收机制,是基于这样一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以擦去不同的
* 回收算法,一面提高回收效率,我们将对象分为三种状态:年轻代,年老代,持久代。JYM将堆内存划分为Eden,Survivor
* 和Tenured/Old空间。
* 1:年轻代
* 所有新生成的对象首先都是放在Eden区,年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象,对应的是
* Minor GC,每次Minor GC会清理年轻代的内存,算法采用效率较高的复制算法,频繁的操作,但是会浪费内存空间,
* 当“年轻代”区域存放满对象后,就将对象存放到年老代区域。
* 2:年老代
* 在年轻代中经理了N(默认15)次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的
* 都是一些生命周期较长的对象。年老代对象越来越多,我们就需要启动Major GC和 full GC(全面回收),来一次大扫除,
* 全面清理年轻代区域和年年老代区域。
* 3:持久代
* 用于存放静态文件,如java类,方法等,持久代对垃圾回收没有显著影响。
*
* Minor GC:
* 用于清理年轻代区域,Eden区满了就会触发一次Minor GC,清理无用对象,将有用的对象复制到“Survivor1",
* "Survivor2"区中(这两个区,大小空间也相同,同一时刻Survivor1和Survivor2只有一个在用,一个为空)
*
* Major GC:
* 用于清理老年代区域。
*
*
* Full GC:
* 用于清理年轻代,年老代区域,成本较高,会对系统性能产生影响。
*
*
* 垃圾回收过程:
* 1:信创建的对象,绝大多数都会存储在Eden中,
* 2:当Eden满了(达到一定比例)不能创建新对象,则触发垃圾回收(GC),将无用对象处理掉,然后剩余对象复制
* 到某个Survivor中,如s1,同时清空Eden区。
* 3:当Eden区再次满了,会将S1中的不能清空的对象存到另外一个Survivor中,如S2.同时将Eden区中的不能清空的
* 对象,也复制到S1中,保证Eden和s1,均被清空。
* 4:重复多次(默认15)Survivor中没有被清理的对象,则会复制到老年代Old(Tenured)区中。
* 5:当Old区满了,则会触发一个一次完整的垃圾回收(Full GC),之前新生代的垃圾回收成为(minor GC);
*
*
*
* JVM调优和Full GC
* 在对JVM调优的过程中,很大一部分工作就是对于Full GC的调节,有如下原因可能导致Full GC:
* 1:年老代(tenured)被写满
* 2:持久代(Perm)被写满
* 3:System。gc()被显示调用(程序建议GC启动,不是调用GC);
* 4:上一次GC之后Heap的各域分配策略动态变化。
*
*
*
* 开发中容易造成内存泄漏的操作
* 1:创建大量无用对象
* 比如,我们在需要大量拼接字符串时,使用了String而不是StringBuilder。
* String str="";
* for(int i =0 ;i<10000;i++){
* str+=1;//相当于产生了10000个String对象
* }
* 2:静态集合类的使用
* 像HashMap。Vector,List等的使用最容易出现内存泄漏,这些静态变量的生命周期和应用程序一致,
* 所有的对象Object也不能被释放。
* 3:各种链接对象(I/0)流对象,数据库连接对象,网络连接对象)未关闭。
* 4:监听器的使用
*
* 要点:
* 1:程序员无权调用垃圾回收器
* 2:程序员可以调用System.gc(),该方法只是通知JVM,并不是运行垃圾回收器,尽量少用,
* 会申请启动Full.GC,成本高,影响系统性能。
* 3:finalize方法,是java提供给程序员用来释放对象或资源的方法,但是尽量少用。
*/