java垃圾回收器

         程序员 了解初始化的重要性,但是往往会忘记同样重要的清理工作。当你创建一个对象的时候,开辟了一块内存区域,很明显,如果你对它“置之不理”,总有一天它就是压死你的最后一根稻草。这里我不想讨论C++,我在乎的是我的最爱java.

        毫无疑问,java的GC为开发人员省下了大部分时间用与处理内存回收问题。java中没有提供像C++里面的析构函数用于释放资源,回收内存空间,但是它提供了方法finalize,千万不要把它就当成了析构函数,在C++中其实对象一定会被销毁的,当然是你的程序不存在bug,然而在java中你需要记住:

                                       1. java对象可能不被垃圾回收                            2. 垃圾回收不等于析构。

我们可以简单的这样来定义java的垃圾回收:一旦垃圾回收器准备释放对象的存储空间,将首先调用 finalize方法做一些重要的清理工作,记住这时候是没有回收存储空间,等到下一次回收动作发生的时候,才会真正的回收对象占用的内存空间。

       在我看来,java的GC实现得益于java的单根继承统一内存堆分配,java是杂合性语言,如果说java里面一切皆为对象,我想没有那本教科书是这么写的,我想读者你应该明白了我为什么这么说。但如果你说 java对象都在堆上 或者 堆上面存储的都是对象 ,这是可以肯定的。下面就来说说GC的神奇吧。

      一.   java中内存的对象类型:

        1. 活动对象:即当前正在其他对象引用的对象'

       2. 非活动对象:这类对象不再被其他对象,堆栈或静态存储区所引用,是孤立的对象。这类对象可以被回收,回收的堆空间用于分配给其它新创建的对象。

 

     二.   GC何时会被触发

          a.  系统空闲 ,GC线程的优先级低于系统应用线程,当系统中没有应用线程执行时,GC会被触发。

          b.  堆空间内存不足,当堆空间的内存不足以创建新对象时,GC会被触发。如果第一GC仍不能获得足够的空间,第二次GC将被触发,如果这一次仍无法获取足够的空间,“Out of Memory” 将被抛出。

     三.  影响GC执行时间、频度的因素

           JVM (heap)空间的大小, 堆空间设置偏大,完全GC执行比较耗时,但执行频率会降低。堆空间设置恰好符合应用内存需求,完全GC执行很快,但执行会变得更频繁。

    四.  堆(heap)空间

            堆是java程序中对象存活的地方,其中包括:活动对象; 非活动对象,这类对象不再为应用程序中的任何指针能够到达; 剩余内存.

         堆空间中包含三种区域:

新生代(younggeneration)

新生代被分为两块: Eden, survivor spaces

i. Eden是为新对象分配的地方,很多对象分配后就变成非活动对象,即垃圾对象。这类对象具有“infant mortality”(幼儿死亡率)。如:方法体中的临时对象。

ii. Survivor spaces也被称为两片生存空间,其中一片要保证任何时刻是空的,并作为下一个空间的目的地。当GC发生的时候,Eden中的存活对象被移入下一片空间。对象在生存空间之间移动,直到它们老化(达到存活时间阀值),然后被移入旧生代。

iii. Eden中对象满的时候,发生一次小收集(minor  collection),小收集执行时间取决于Eden中对象的infant mortalityinfant mortality高,执行就会很快。

旧生代(tenuredgeneration)

a. 该区域用于存放那些生命周期比较长的对象,Eden中的活动对象经过minor collection后,被复制到两片生存空间,当两片生存空间中的对象老化时,这些对象被移入旧生代。

b.旧生代中对象满的时候,发生一次大收集(major collection),因为收集时要涉及所有存活对象,所以大收集的速度相对于小收集要慢很多。

永生代(permanentgeneration)

这个代比较特别,它负责保存反射对象。这些数据是虚拟机所需的数据,用来描述在Java语言中没有等同物的对象。例如,描述类与方法的对象存储在永生代中。

 

五.  回收机制

遍历堆栈或静态存储区的引用找对象, java中采用“自适应技术”,当垃圾回收器第一次启动时,它执行的是停止-复制,因为这个时刻内存有太多的垃圾。然后Java虚拟机会进行监视,如果所有对象都很稳定,垃圾回收器的效率降低的话,就切换到标记-清扫方式;同样,Java虚拟机会跟踪标记-清扫效果,要是堆空间出现很多碎片,就会切换到停止-复制方式。这就是所谓的自适应技术。

i.停止-复制

理论上是先暂停程序的运行(所以它不属于后台回收模式),然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全是垃圾。当对象被复制到新堆上时,它们是一个挨着一个的,所以新堆保持紧凑排列(这也是为什么分配对象的时候堆指针只管依次往前移动)。然后就可以按前述方法简单、直接地分配内存了。这将导致大量内存复制行为,内存分配是以较大的为单位的。有了块之后,垃圾回收器就可以不往堆里拷贝对象了,直接就可以往废弃的块里拷贝对象了。

ii. 另一种是标记-清扫:它的思路同样是从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象。每当它找到一个存活对象,就会给对象一个标记。这个过程中不会回收任何对象。只有全部标记完成时,没有标记的对象将被释放,不会发生任何复制工作,所以剩下的堆空间是不连续的,然后垃圾回收器重新整理剩余的对象,使它们是连续排列的。     

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值