对于初学Java的可以看看这两本书:《深入理解Java虚拟机》和《Thinking in Java》。
首先了解一下Java垃圾回收机制。
Java垃圾回收机制主要有两个方面,一是垃圾回收算法,二是垃圾回收器。
1、引用计数算法
堆中的每个对象有一个引用计数器(初始值为0),当有引用连接对象的时候,引用计数器加1。垃圾回收器开始作用的时候,会在堆中遍历,把引用计数为0的对象都释放。
优点:可以避免FULL GC时带来的程序暂停,如果读过Redis 1.0的源码,可以发现Redis中就是在引用计数器为0时,对内存进行了回收
缺点:不能解决循环引用的问题、
2、标记-清扫算法
找出堆中所有存活的对象,每找到一个存活的对象,就会给对象设一个标记,这个过程不会回收任何对象。只有当全部标记工作完成的时候,清理动作才会开始。在清理过程中,没有标记的对象会被释放。
优点:释放缓存,能够提升程序的性能,
缺点:所剩下的堆控件是不连续的,产生了大量不连续的内存碎片,空间碎片太多可能会导致在程序运行过程中要分配较大的对象的时候,无法找到足够的连续内存而不得不提前出发垃圾收集动作。
3、复制算法
复制算法将内存划分为两个区间,在任意时间点,所有动态分配的对象都只能分配在其中一个区间(称为活动区间),而另外一个区间(称为空闲区间)则是空闲的。 当有效内存空间耗尽时,JVM将暂停程序运行,开启复制算法GC线程。接下来GC线程会将活动区间内的存活对象,全部复制到空闲区间,且严格按照内存地址依次排列,与此同时,GC线程将更新存活对象的内存引用地址指向新的内存地址。此时,空闲区间已经与活动区间交换,而垃圾对象现在已经全部留在了原来的活动区间,也就是现在的空闲区间。事实上,在活动区间转换为空间区间的同时,垃圾对象已经被一次性全部回收。
优点,实现简单,运行高效、
缺点,代价很大,相当于将可以使用的内存缩小为了原来的一半。 还浪费资源
4、标记-整理算法
找出堆中所有存活的对象,每找到一个存活的对象,就会给对象设一个标记。让所有存活的对象移动到内存的一端,然后直接回收掉端边界以外的其他对象。(移动的过程不回收对象)
5、分代收集算法
Java程序员学习交流群515675832,既有技术大佬,又有老司机开车,各位对Java感兴趣的可以来交流学习一下,快乐与技术一起进步。