zoukankan      html  css  js  c++  java
  • gc

    gc即垃圾回收。

    .net和java开发时,我们不再需要关注内存的创建和销毁。.net的clr和java的jvm来帮我们管理内存。但是了解gc的一些原理和过程还是有好处的。

    总的来说,gc要解决以下这几个问题:

    1.什么是垃圾

    2.怎么回收垃圾

    1.什么是垃圾

    垃圾就是一段不再使用的内存。应用程序创建的对象会分配在堆上。由于开发不再自己手动销毁对象,随着程序的运行,堆上的对象越来越多。如果不进行清理,内存就会耗尽。这时候,gc就要进行清理了。

    什么对象是垃圾呢?

    最早的gc是根据引用计算器来判断对象是否是可用的,是否是垃圾。

    现在的gc都是根据循环查找来判断对象是不是垃圾。从一些根对象开始,递归查找那些可达的对象,剩下的都是不可达的,那些不可达的对象就是垃圾。

    什么是根对象呢?

    1.GC发生时,当前正在执行的方法中那些本地变量/参数。

    2.静态变量

    3.非托管类似COM+一样通过interop被使用的对象

    4.实现了finalizer接口的对象

    早期的应用计算器算法,对于那些循环应用的对象是无能为力的。从根对象递归查找来判断是可以解决循环应用的问题的。

    2.怎么回收垃圾

    回收垃圾时,gc将那些被标记为垃圾的对象在堆上进行清理,然后将剩下的不是垃圾的对象压缩在一起,减少内存碎片。

    由于在压缩的时候,堆上的对象的地址发生了改变,所以,引用这些对象的指针变量也需要指向新的地址。垃圾回收可以简单的认为有这几个过程:

    1.将被标为垃圾的对象进行回收。

    2.将不是垃圾的对象进行压缩,减少内存碎片

    3.由于第2步,对象的地址发生了,改变。指向该对象的指针变量也需要指向新的地址。

    当垃圾回收开始时,所有工作线程必须挂住,因为这些对象的指针会发生改变。等gc完成后,挂起的线程再继续执行。

    gc中还有个概念是分代回收。

    如果每次gc都堆上所有的对象进行扫描,是很消耗时间的。

    gc中对堆上的对象进行分代。目前有0代,1代和2代。有了代的概念,gc时,就可以只对其中某一代进行回收。或者对某几代进行回收。

    但应用初始化完成时,堆上没有数据。随着应用的运行,堆上开始有了新对象。这些对象都是0代的对象。随着对象的越来越多,要进行gc了。gc对堆上所有的对象进行扫描,标记垃圾,将垃圾进行清除。gc结束后,那些没有被回收的对象就从0代变成了1代。这之后新创建的对象就成了0代。随着对象越来越多,进行第二次gc。gc过后,1代对象成为2代对象。0代成为1代对象。gc过后,新创建的对象成为了0代对象。再进行gc时,那些2代对象,还是2代对象,目前还不存在3代对象。

    在进行gc时,可以只回收0代的对象。如果0代回收掉后,内存还不够,再回收1代对象。如果1代回收后,仍不够,再回收2代对象。分代回收是为了提高性能。微软和java一直在优化内存回收的算法来提高性能。里面具体的实现细节可能会有改动。但总的思路是不变的。

  • 相关阅读:
    IIS6.0中,使用其它用户运行IIS
    c++构造函数详解
    Java创建文件夹及文件
    三大范式及存储方式
    对新型软件程序语言及架构的一点讨论
    C++虚函数解析
    验收测试驱动开发:ATDD实例详解
    什么是父路径及开启的方法
    note:全局配置visual studio 2010 头文件目录
    怎么把二级域名重定向到主域名
  • 原文地址:https://www.cnblogs.com/leiwei/p/3706888.html
Copyright © 2011-2022 走看看