当一个对象的引用不在使用,但仍占用内存空间时,则被认为是垃圾对象。
二、怎么判断垃圾对象目前java中可作为GC Root的对象有
① 虚拟机栈中引用的对象(本地变量表)
②方法区中静态属性引用的对象
③ 方法区中常量引用的对象
④本地方法栈中引用的对象(Native对象)
三、什么时候进行垃圾回收 1、JVM自己决定什么时候垃圾回收(由四给出的算法机制决定)。 2、程序员人为的触发System.gc()方法,向系统发出垃圾回收请求,但最终是否回收,由系统决定。 注意:Java提供finalize()方法,为了释放“特殊”内存区域(非new获得的区域),Java允许类定义一个finalize()方法,垃圾回收器释放对象时,将首先调用其finalize()方法。标记-清除算法采用从根集合进行扫描,对存活的对象对象标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收。标记-清除算法不需要进行对象的移动,并且仅对不存活的对象进行处理,在存活对象比较多的情况下极为高效,但由于标记-清除算法直接回收不存活的对象,因此会造成内存碎片!
2、复制算法
复制算法采用从根集合扫描,并将存活对象复制到一块新的,没有使用过的空间中,这种算法当控件存活的对象比较少时,极为高效,但是带来的成本是需要一块内存交换空间用于进行对象的移动。
3、标记-整理算法
标记-整理算法采用标记-清除算法一样的方式进行对象的标记,但在清除时不同,在回收不存活的对象占用的空间后,会将所有的存活对象往左端空闲空间移动,并更新对应的指针。标记-整理算法是在标记-清除算法的基础上,又进行了对象的移动,因此成本更高,但是却解决了内存碎片的问题。
4、基于新生代---年老代的算法
JVM将堆分为Young区、Old区和Perm区 Yong区:又分为Eden区和两个Survivor区,新创建的对象都在Eden区,当Eden区满时,触发minor GC将Eden区仍存活的对象复制到一个Survivor区,另一个Survivor区存活的对象也复制到这个Suevivor区,为了保证始终有一个Survivor区是空的。 Old区:存放的Young区的Survivor满后,又有对象要加入Survivor区,则GC收集器将Survivor区的对象直接放到Old区。如果Survivor区中对象足够老,也存放到Old区。如果Old区满了,则触发Full GC,回收整个堆内存。 Perm区:存放的主要是类对象,如果一个类被频繁的加载,也会导致Perm区满,Perm区回收也是Full GC触发。
新闻热点
疑难解答