zoukankan      html  css  js  c++  java
  • 内存管理初探

    内存管理初探_枫风的BLOG_百度空间

    内存管理初探

    最近对内存管理接触多些,就稍微研究了一下。主要分为两个部分,一是动态内存分配,二是垃圾回收。以下是对理论部分的简要回顾:

    【动态内存分配】

    1、uClibc的内存分配
    uClibc的内存分配是在堆上进行的,采用空闲链表进行管理,对内存申请使用最先适应(first fit)算法。如果堆大小不够,则调用sbrk/mmap系统调用向系统申请扩展堆空间;如果有大量空间被释放,则调用mumap缩小堆空间。个人以为频繁调用malloc/free的开销主要在系统调用上面。

    2、Linux内核的内存分配
    Linux内核中,大块内存是采用分页管理,每个页面大小为4K,对内存申请使用伙伴算法;小块内存采用对象缓冲池方式,建立一系列不同大小的缓存对象缓冲池,对常用的对象建立该对象大小的缓冲池,对小块内存申请建立2的幂数大小的缓冲池,在缓冲池中进行内存分配。

    3、Python的内存分配
    与Linux内核的实现方式类似,Python也对大内存和小内存分别实行不同的分配方式。其中大内存直接调用malloc进行分配,而小内存则使用缓冲池方式。在缓冲池中包括block、pool和arena三个层次:block为内存分配的基本单位;pool为block的集合,一般大小为4K,一个pool只能包含一种大小的block;arena为pool的集合,默认大小为256K。

    【垃圾回收】

    1、引用计数(reference counting)
    引用计数是最经典的垃圾回收算法,也是Python正在使用的垃圾回收算法。主要思想是在对象中加入一个域进行引用计数,新建对象的引用计数为1,以后每有对象指向它时就把计数加1。当引用计数为0时,即可认为该对象为垃圾,可以进行垃圾回收。引用计数的优点是简单,且把垃圾回收的成本平均在运行时间,缺点是存在循环引用问题。

    2、标记清除(mark-sweep)
    标记清除是从根对象(包含全局对象和当前栈中的活动对象)出发,利用广度遍历找出所以可达的对象(即根对象直接或间接引用的对象)并进行标记,其它所有未标记的对象为不可达对象,也即垃圾,可以进行垃圾回收。该算法成功解决了循环引用问题,但因为垃圾回收动作比较集中,容易对实时性要求比较高的系统产生性能影响。

    3、复制回收(copying collection)
    复制回收是在系统中建立两个堆,同时只有一个堆是使用的,另一个堆用于在垃圾回收时把可达的对象复制进去。该算法的优点是可避免内存碎片,但因为需要同时存在两个堆,所以内存浪费比较大。

    4、分代收集(generation collection)
    该算法的主要思想是大部分的新对象生命周期比较短,而存活时间比较久的对象是垃圾的可能性比较小。所以,它会把对象分为几代,新创建的对象在最年轻一代,如果经历几次垃圾收集后该对象依然存在,则把它移到上一代中。回收时,一般只回收最年轻的一代。该算法的优点是效率比较高,且可以对不同的代使用不同的垃圾回收算法,但由于本质上它是一种以空间换时间的算法,所以存在着内存浪费。
  • 相关阅读:
    CSS浮动(float、clear)通俗讲解
    JAVA 类的加载
    数据库操作 delete和truncate的区别
    正则表达式 匹配相同数字
    Oracle EBS OM 取消订单
    Oracle EBS OM 取消订单行
    Oracle EBS OM 已存在的OM订单增加物料
    Oracle EBS OM 创建订单
    Oracle EBS INV 创建物料搬运单头
    Oracle EBS INV 创建物料搬运单
  • 原文地址:https://www.cnblogs.com/lexus/p/2960858.html
Copyright © 2011-2022 走看看