给对象添加一个计时器,
只要对象被其他对象引用,让记数+1; 若变量不再引用了,让记数-1 ;当引用为0则回收
缺点:当循环引用时会造成内存泄漏 !

A和B的引用记数都是1,而没有其他对象引用A或B,导致记数无法归零,造成内存泄露------------早期python虚拟机使用的引用计数法,而java用的是可达性分析法;
【在垃圾回收前】,会对堆中的所有对象扫描,找出是否有对象被GC root根对象引用,如果是则不能被回收,反之一个对象没有被根对象直接/间接引用,则可以被回收。
哪些是GC root根对象?

1.系统类的对象
2. 本地方法栈引用的对象
3. 线程中虚拟机栈 栈帧所引用的对象
4. Monitor对象即正在加锁的对象
( GC root根对象指的是堆中的对象实体,而不是引用 )
对于一个对象来说,只要有强引用的存在,它就会一直存在于内存中
如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它; 如果内存空间不足了,就会回收这些对象的内存
一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的空间
如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
平时用的所有引用都是强引用,即传统的引用,如new 对象把对象赋给引用变量,则这个变量强引用了刚刚的对象;除非当根对象不再引用时会被回收。当对象被强引用时,处于可达状态,不可能被回收,即使以后都不会用到,所以强引用是造成内存泄漏的主要原因
软引用用来描述一些还有用,但非必须的对象,
弱引用也是用来描述那些非必须的对象,但是强度比软引用更弱一些,弱引用关联的对象只能生存到下一次GC手收集发生为止
虚引用是最弱的一种引用关系,无法通过虚引用来取得对象实例,主要配合bytebuffer使用,给一个对象设置虚引用关联的目的在于能在这个对象被GC回收时收到一个系统通知。
使用可达性分析法,沿着GCroot的引用链去找,扫描整个堆中对象,如果对象被GCroot根对象引用,则保留
①将未被根对象引用的对象标记;
②清除;

优点:速度快,只需要将内存的起始地址做一个记录就完成了
缺点:容易产生内存碎片;清除后不会再对空闲的空间进行整理工作了,即空闲的空间不连续,当有大的新对象的时候,放不下!造成内存溢出;
第一个阶段和标记-清除中一样
①使用可达性分析法,将未被根对象引用的对象标记;
②通过紧凑技术解决标记-清除算法的内存碎片问题,通过将可用的对象向前移动,让内存更为紧凑,连续的空间更多;

优点:没有内存碎片
缺点:整理涉及到了对象的移动,对象移动涉及到引用地址的改变,效率较低;
标记-整理算法中对象可能会移动多次,而标记-复制算法中只需要移动一次。
①使用可达性分析法,在FROM区域,将未被GC root根对象引用的对象标记
②将FROM区域存活的对象,复制到TO区域,复制过程中会完成内存碎片的整理,复制完成后,FROM区域全是垃圾,
③清除FROM区域的所有垃圾
④交换FROM和TO区域



优点:不会产生内存碎片,只需要移动一次对象,而标记-整理算法是移动多次
缺点:占用双倍的内存空间
仅适用于单线程Serial、并行Parallel 垃圾回收器, 而并发的CMS、G1在老年代的机制不同!

堆内存被划分为两块:新生代和老年代 ;
新生代划为:Eden伊甸园 survior幸存区(From + to);
新生代:一般保存新出现的对象,通常在每次垃圾收集时都会有大批对象死去,需要频繁的去回收,只有少量对象存活,便采用了标记-复制算法,只需要移动少量存活对象即复制开销小,就可以完成收集;
老年代中一般保存长时间存活、更有价值的对象,他们存活率高、没有额外空间对它进行分配担保,就必须采用 标记-清理 或者标记-整理算法;
永久代就是JDK1.7之前的方法区。在这里都是放着一些被虚拟机加载的类信息,静态变量,常量等数据。这个区中的东西比老年代和新生代更不容易回收。
老年代的垃圾回收很久才进行一次,新生代的垃圾回收更频繁;

minor gc / full gc会引发stop the world,会暂停其他的用户线程,由gc线程完成垃圾回收,其他的用户线程才能继续运行
原因: minor gc运行时,对象的内存地址会发生改变,如果多个线程同时运行,会造成混乱!等gc结束之后,用户线程恢复运行
新生代大部分都是垃圾,存活率低,需要复制到幸存区TO区域的对象少,所以stop the world很快就能完成;
老年代存活率高,stop the world需要的时间更长
空间:

为什么新生代要分Eden和两个 Survivor 区域?
①Survivor的预筛选保证,就是减少被送到老年代的对象,进而减少Full GC(进行一次Full GC消耗的时间比Minor GC长得多)
②使用标记-复制算法,解决了内存碎片问题

串行垃圾回收器分为两部分:Serial + SerialOld;
serial工作在新生代,采用标记-复制算法
serialOld工作在老年代,使用标记-整理算法;
过程:(完全stop the world)

当发现内存不够了,触发gc,让线程在安全点停下 (stop the world)即阻塞,然后让gc线程(单线程),等待gc结束,其他线程再运行。

也是完全 stop the world,并开启多个线程进行回收;
