dlmalloc 2.8.6 源码详解(1)

研究dlmalloc和dlfree算法 一.背景知识 内存模型 我理解的是,在内存里面会划分很多个segment,每个segment有对应的state(存储bins,dv,top等重要全局信息,便于后续分配内存块chunk/treeChunk),base,size,next,sflags属性,包含了top chunk,chunk,tree chunk内存块。 state 下图中,state比较重要的属性是橙色背景的。 chunk和tree_chunk tree_chunk仅比chunk多child和parent属性。 smallBins 数 阅读详情
AI摘要

本文全面阐述了著名内存分配器dlmalloc的设计思路与实现手法。dlmalloc由Doug Lea编写,因其出色的性能表现,在C库内存分配领域占据重要地位。文章介绍了内存分配的基本原理,详细解释了dlmalloc中涉及的概念和技术,如chunk、bin、mspace等,并通过实例讲解了位运算在内存对齐中的应用。

本文章由vector03原创, 转载请注明出处.

邮箱地址: mmzsmm@163.com, 欢迎来信讨论.

 

前述

Dlmalloc是一个著名的内存分配器,最早由Doug Lea在1980s年代编写.由于早期C库的内置分配器在某种程度上的缺陷,因此dlmalloc出现后立即获得了广泛应用,足见其出色的表现.尽管时至今日, dlmalloc中的技术在一些地方已然落后于时代,很多优秀的allocator如google的tcmalloc, freeBSD的jemalloc等在某些情况下性能可以达到dlmalloc的数十甚至上百倍.但前者的很多思想和基本算法对后来者产生了深远的影响.走进memory allocator的神秘世界, dlmalloc可说是最好的教材之一.

本篇文章试图以初学者的角度全面阐述dlmalloc的设计思路和基本实现手法,以及内存分配相关的一些基础知识.事实上,内存分配器的设计思路和我们日常生活中”批发-零售”的概念是一致的,很多看似复杂的算法的基本原理都比较好理解.但是从实现的角度说,如果真的完全看懂dlmalloc的代码,则需要极大的耐心.因为Doug Lea本人在这份代码中使用了大量的技巧,对于初次接触此类代码的人来说,很多写法非常的古怪.然而当你耐下心细细体会作者的思路和意图之后,会对之心悦诚服,感受到其匠心独到之处.这对于开拓自身的编程视野也是具有莫大帮助的.

文档中使用的代码基于android4.4上的malloc版本.源代码位于目录,

bionic\libc\upstream-dlmalloc\Malloc.c

最新版本的dlmalloc源码请参考该网址,

ftp://gee.cs.oswego.edu/pub/misc/malloc.c


 

1. 基础知识

在正式开始介绍dlmalloc之前,首先需要了解一些与之相关的基础知识,否则基本上很难看懂dlmalloc的代码和文档.

1.1 内存分配原理

最早接触C/C++这类语言时, malloc/free或者new/delete都是常常被提及的.这些函数或运算符无论参数还是返回值都非常简单.但具体来说,内存到底是如何从硬件上某个内存颗粒中的地址单元里,一路返回到程序员的手里呢?这绝非一个简单的过程,事实上整个过程相当之复杂.另外,我们需要探讨的内存分配器在其中又是扮演哪个角色呢?

 

       上面的图大致上描述了内存分配的过程,注意这只是一个示意图,它并不是很精确.首先我们需要知道的是allocator与普通程序一样都工作在用户态,并且其本身也是作为system heap的一部分。当用户通过malloc之类的库函数提交分配请求后,将首先由allocator查找,如果在其内部保留的空间中找到满足需求的内存块,就将之返回给用户(一般都是相对较小的块).如果找不到合适的块,则进一步向system发起请求,将划分system heap上的一部分给allocator,再由后者划拨给用户.另一方面,在划拨heap空间后,这部分新生成的空间其实还无法直接使用,系统会在合适的时机,通过名为MMU的硬件将实际物理内存上的某些区域(以page为单位),映射到需要使用的线性地址上.这样就完成了一块内存从申请到使用的全过程.

从这些描述上, 你可能会感受到一点, allocator和system之间的关系就如批发和零售的关系一样. System作为批发商,手中握有大量的待批商品——线性地址.而allocator作为零售商,会不定期的从批发商手里提货,将这些一次性批来的地址再进行二次管理.当用户程序作为顾客,向零售商购买商品时, allocator的整套算法都是为了保证尽可能的将货都卖出去而不砸在手里,也就是尽量避免在尚有存货的情况下向批发商购进新的货品.同时,它还要保证能在最快的时间将这些货卖出去. Allocator的初衷就是帮助用户程序又快又好的管理system heap中的内存.


1.2 Linux进程地址空间

说到system heap,需要了解一下进程的线性地址空间布局.如图所示,

关于此类内容, 介绍计算机体系架构的书中会有详述, 此章节做一个简单的介绍.当应用程序的二进制映像被加载到一个32bit机器的进程地址空间后,会被定位成如下的区域(这里与有些资料上介绍的略有不同,基本上该图会更加准确一些).从低地址到高地址分别为,

最开始的一段区域为保留区域, 这里并不存放有效的代码和数据.

之后从某一个地址开始, 为程序的入口点(C语言在该地方会有一句跳转,进入__cinit()).往上为代码段,存放编译好的二进制映像,基本上是一些指令,常量和字符串.

代码段之上是数据段, 存放所有全局和静态变量.

数据段再往上是bss段,存放所有未初始化的全局和静态变量.在程序一开始这段区域是一大片0.数据段和bss段也被合称为静态区.

数据段之上也就是我们平时常称作heap的堆区.注意heap是从低到高向上生长的,另外在heap一开始会有一段随机长度的offset区,加入这个主要是为了防止恶意代码的溢出型攻击.因为只要保证堆的基址每次都是随机的,就无法通过将恶意跳转指令插入到某个固定地址而导致因缓冲区溢出造成系统控制权丢失.

再往上是一大片未开垦的荒芜之地,虽然图上画的很小,但实际却很大.在通过系统调用申请之前,这片地址是既不可写也不可读的,否则会导致segmentation fault.

在中间的空洞之上是另一片比较大的区域,为mmap区.这片区域主要是保存文件映射,包括程序中使用的动态链接库so的映射,以及匿名文件映射,或者程序中共享数据用的手动映射.这部分区域是从高地址向低地址扩展.同样,在mmap区之上,也存在一片用于防止溢出的随机offset区.

接着向上, 就是被称作stack的栈区.图中有些误导的是栈区其实本来是无法扩展的,最大容量是一早在内核中设定好的.这里标示的stack向低地址grows down指的是栈顶sp指针的生长方向.因此一旦sp超过这段区域的设定下限,就意味着爆栈了.同样stack之上也存在防止溢出的随机offset区.

前面说的所有区域, 在32bit机器上加起来为3GB大小.这3GB被称作进程的用户空间,在不同进程之间是不可见的(fork的父子进程某些值在写入前虽然是一样的,但写入后也是不一样的).之所以可以做到这一点在于每个进程控制块中保存了各自的页表目录和页表,这样通过MMU查询到的物理页面其实根本是两个地址.具体信息请查阅linux下mm的相关部分.

最后, 最高地址的1GB空间为系统所有的内核空间,所有内核代码包括内核驱动都执行在这部分中.与用户空间不同的是,内核空间的映射是固定的,因此不同进程虽然有自己的用户空间,却有着相同的内核空间.显然这部分地址也是我们用户无法直接读写的(可以通过驱动将内核空间的地址和用户空间映射在一起以实现访问).

通过上面的介绍, 可以看到应用程序的内存分配事实上是通过在中间空洞两边的heap区和mmap区相对生长来完成的.因此我们常说的动态内存在堆区分配其实是不准确的.

1.3 术语

介绍dlmalloc之前,还需要了解一些相关术语及其含义,这些到后面就不再做过多解释了.

Payload: 有效负载.指的是实际交给应用程序使用的内存大小.

Overhead: 负载,开销.本意是为了满足分配需求所消耗的内存量,实际在代码注释中多指除了payload之外的额外开销(有些书中也称之为cookie).

Chunk: 区块.是内存分配的基本单位,类似物质世界中的原子不可再分. dlmalloc对内存的管理基本上都是以chunk为单位.一个典型的chunk是由用户程序使用的部分(payload)以及额外的标记信息(overhead)组成.

Bin: 分箱.用来管理相同或同一区间大小的chunk.在dlmalloc中分为sbin和tbin两种.

Mspace: 分配空间.说白了就是dlmalloc中内存池的叫法.在dlmalloc中可以管理多个mspace.如果不显式声明,将会使用一个全局的匿名空间,或者用户可以自行划分空间交给dlmalloc管理.

Segment: 区段.一般情况下,内存分配都是在一片连续区间内开采(exploit).但也会遇到不连续的情况,这就需要分成若干个区段记录.多个区段可以同属一个mspace.

Fenceposts: 栅栏.大多数分配器中, fencepost起到非连续内存间的隔离作用.一般这种隔离被用做安全检查.分配器会在fenceposts所在位置写上特殊标记,一旦非连续内存间发生写入溢出(overwrite)就可以通过异常的fenceposts值发出警告.

Bookkeeping: 记录信息.不同于每个chunk中的overhead,这里指的是整个mspace控制块的记录信息.往往这部分信息都固定在mspace开始的一段空间,或者干脆就放在地址空间的静态区中.

Granularity: 粒度.这个粒度指的是从system heap上获取内存的最小单位.一般来说该值至少为一个page size, 且必须以2为底.

Mmap: 本意是类unix系统的文件映射调用.但在dlmalloc中表示的更宽泛,这里指代可以在进程地址空间中开辟非连续内存空间的系统调用.

Morecore: 指可以在进程地址空间中开辟连续内存空间的系统调用.在类unix系统下morecore指的是sbrk调用.

Program break: 前面提到的sbrk()实际也是一个库函数,真正起作用的是brk()系统调用.这个函数其实就是break的缩写.所谓的break是一个代表进程heap区top-most位置的指针.当我们通过sbrk/brk向系统请求内存时,系统做的仅仅是移动break指针,内存就这样被划拨到heap中了.而当释放内存时,就反方向移动该指针,内存就返回给系统.

Footprint: 从系统获得的内存量.指的是当前dlmalloc从system heap获取的内存总和.设立footprint一方面是为了方便统计,另一方面也可以限制dlmalloc从系统获取的最大内存量.

Trimming: 裁剪.被dlmalloc管理的内存被free后,并不直接返还给系统,而是当积累到一定程度会通过一些算法判断system heap是否收缩(shrink),这个过程在dlmalloc中称作auto-trimming.

1.4 位运算

Allocator在计算内存大小时为了加快处理速度,会使用大量位运算.基本上很多计算技巧已经成为通用化的公式了.熟悉这些计算方法会对理解dlmalloc的代码有巨大帮助.

这里提一下Doug Lea推荐的一本书《Hacker’s Delight》.该书是一本详细介绍各种位运算奇技淫巧的著作,读之前需要做好被虐的准备.

1.4.1 地址对齐

我们知道, 在计算机硬件体系结构中,内存的读写必须是对齐到某一个数值上的,比如常见的32bit机器对齐在4字节上.那么诸如0x08000003这样的地址就不能被直接访问.

判断一个地址或一段长度是否对齐到某个边界上其实就是判断该值能否被对齐边界整除.我们以对齐到8上为例, 24/8 = 3余0,说明是对齐的.而27/8 = 3余3,就不是对齐的.从代码角度考虑,很容易得到这样的结果,

显然, 取模运算的性能代价相对于allocator来说是巨大的,有必要考虑其他的方法.前面说到,所有硬件体系都需要内存读写对齐到某一数值上,但还有一点没有提及,就是该数值必须是以2为底的指数.这一次,我们将所有的除数和被除数用二进制来表示,

24 / 8           11 000b / 1 000b     = 11b    mod  0

35 / 8           100011b / 1 000b = 100b  mod  11b

50 / 8           110101b / 1 000b    = 110b  mod  101b

126 / 8         1111110b / 1 000b = 1 111b   mod  110b

我想你可能发现了一个有趣的规律, 8相当于23,而所有被8除的结果中,在二进制下余数都是被除数的最后3位.是否说如果n相当于2m次幂,则A除以n的余数相当于二进制下A的最后m位呢?答案是肯定的.换句话说,上面的判断中,如果我们能知道n是2的几次幂就可以通过取出A的最后m位来判断是否对齐.

以2为底的指数在二进制下还有一个有用的特性,

比如, 8的二进制表示为1000b,而 8 – 1表示为111b.

16的二进制表示为 10000b,而 16 – 1表示为1111b.

而32的二进制表示为100000b, 32 – 1表示为11111b.

这样我们又发现了第二个规律, 以2为底的m次幂的二进制数减去1时,由于连续借位,最终出现除了MSB之外,低位全部被1填充的情况.因此我们有,

如果n为以2为底的m (m > 0, m = 1, 2, 3, …)次幂指数,当以n为对齐边界时,称n – 1为该对齐边界的对齐掩码(align mask).

了解上面的两个特性后, 判断某地址是否对齐到以2为底的指数时就变得简单了,只要将原数值与对齐掩码作与,判断结果是否等于0即可,

1.4.2 上对齐与下对齐

那么对于一个非对齐的数值进行处理实际上存在两种方式,上对齐(align up)和下对齐(align_down).还是以8为对齐边界来讨论,

图中, 28如果采用下对齐的方式,对齐到24,则只需要简单舍去其余数即可.操作的方法有两种,一种是先右移再左移的方式,

或者, 直接使用对齐掩码的方式,

如果选择上对齐, 则需要另外的方法,

如上图所示, 首先将28加上一个偏移,使其跳跃到下一个对齐区间里去,然后再对其使用下对齐方式,就间接实现了在当前区间中上对齐.这个偏移值为对齐边界减1.为什么这里会减1呢?这里与对齐掩码什么的无关了,因为若被对齐数本身已经处于对齐状态,再加上一个对齐长度并与对齐掩码运算后就会留在下一个对齐区间中,这个结果显然是不正确的了.因此得到的代码如下,

这个宏就是可以被作为公式的内存对齐宏.

1.4.3 计算对齐偏移量

有时候不需要直接获取对齐后的地址,而是计算出一个对齐偏移量,

这个宏看起来复杂, 其实就是前面的组合, 首先判断是否已经对齐,如果是则偏移量为0.没有对齐则用n – A & (n-1)获取偏移量,再与上对齐掩码保证位数正确.事实上,大多数机器上后面的与操作其实是多余的.

dlmalloc-2.6.6源码分析 <br /> <br /><br /><br /> <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />目    录<br /><br />1.Doug Lea malloc简介2<br />2.边界标记3<br />3.分箱管理7<br />4.内存分配相关函数14<br />4.1函数mALLOc( )14<br />4.2函数malloc_update_mallinfo( )22<br />5.内存回收相关函数 阅读详情

相关推荐

dlmalloc说明及代码

dlmalloc是目前一个十分流行的内存分配器,其由Doug Lea(主页为http://gee.cs.oswego.edu/)从1987年开始编写,到目前为止,最新版本为2.8.3(可以从ftp://g.oswego.edu/pub/misc/malloc.c获取),由于其高效率等特点被广泛的使用(比如一些linux系统等用的就是dlmalloc或其变形,比如ptmalloc,主页为http://www.malloc.de/en/index.html)和研究(各位可以搜索关键字“GCspy”)。 dlmalloc的实现只有一个源文件(还有一个头文件),大概5000行,其内注释占了大量篇幅,由于有这么多注释存在的情况下,表面上看上去很容易懂,的确如此,在不追求细节的情况,对其大致思想的确很容易了解(没错,就只是了解而已),但是dlmalloc作为一个高品质的佳作,实现上使用了非常多的技巧,在实现细节上不花费一定的精力是没有办法深入理解其为什么这么做,这么做的好处在哪,只有当真正读懂后回味起来才发现它是如此美妙。 lenky0401个人博客将陆续推出对dlmalloc的解析(针对Doug Lea Malloc的最新版Version 2.8.3,未做说明的情况下以32位平台,8字节对齐作为假定平台环境设置考虑),由于个人水平有限,因此也不能完全保证对dlmalloc的所有理解都准备无误, 但是所有内容均出自个人的理解而并非存心妄自揣测来愚人耳目,所以如果读者发现其中有什么错误,请勿见怪,如果可以则请来信告之,并欢迎来信讨论(lenky0401@163.com)。 这一系列文章是lenky0401在看完dlmalloc的大部分代码后的再总结,不能保证对dlmalloc的整体完全把握,贴出这些只是希望可以提前收到对此有研究的网友的指点,以便在最后对这一系列文章整理而形成的PDF文档中错误能少一些。至于对于现在贴出来的内容中包含的错误给大家造成的不便提前说声抱歉。:) 描述的内容不会包含dlmalloc全部代码,但会将这其中涉及到的一些技巧尽量讲出,我相信对dlmalloc源代码不感兴趣的朋友也可以学到这些独立的技巧而使用在自己的编程实践中。:) 最后,转载请保留本博客地址连接[http://lenky0401.cublog.cn],谢谢。

dlmalloc、ptmalloc与glibc堆漏洞利用

本文主要介绍dlmalloc、ptmalloc的详细原理,并分析几个常见的漏洞利用方法。

有价值炮灰 2026

微信聊天记录丢失原因与恢复方案详解

SQLite数据库作为移动应用常见的本地存储方案,其加密机制和存储结构直接影响数据安全性。以微信为例,聊天记录存储在EnMicroMsg.db等SQLite文件中,采用AES加密保护。当手机清理工具误删这些文件时,会导致特定时间段记录丢失。理解数据恢复原理需要掌握文件系统删除机制和闪存特性,其中关键点包括TRIM指令的影响和数据块覆盖风险。通过专业工具如DiskDigger或iMyFone D-Back,配合ADB调试和SQLite数据重组技术,可在黄金时间窗口内恢复记录。日常维护建议结合自动化备份方案和存

weixin_32612263的博客 386

dlmalloc(一)

我们写过很多C程序了,经常会分配内存。记得刚学C语言时老师说过,可以向两个地方申请内存:一个是栈、一个是堆。小块内存向栈申请,函数调用结束后程序会自动释放内存。大块内存向堆申请,记得一定要自己释放,否则会造成内存泄漏。向堆申请内存直接调用malloc()就可以了,参数是你申请的内存量。释放内存时直接调用free()就可以了,参数是内存块指针。 看似平静的海面,海底则波涛汹涌。当时还没有学操作系统

ycnian 1万+

Zabbix-获取客户端的SNMP数据

网口状态(ifOperStatus)的 OID 是1.3.6.1.2.1.2.2.1.8,查询时需要用1.3.6.1.2.1.2.2.1.8.1(第 1 个网口)、1.3.6.1.2.1.2.2.1.8.2(第 2 个网口)等。表格对象是指 “包含多个同类实例的对象”(如设备的多个网口、多个进程等,每个实例需要单独标识)。在 SNMP 规范中,标量对象的完整 OID 必须以.0结尾,.0是标量对象的唯一实例编号。标量对象是指 “单一值的对象”(如设备的名称、温度、状态等,整个设备只需要一个值来表示)。

徐子元 1733

自回归分布滞后模型 (ARDL)及 Stata 具体操作步骤

例如,Bahmani-Oskooee 和 Brooks(1999)研究了汇率波动与贸易收支之间的关系,发现汇率的变动在长期和短期内对贸易收支的影响存在差异,ARDL 模型能够有效地捕捉这种复杂的关系。它结合了自回归(Autoregressive,AR)模型和分布滞后(Distributed Lag,DL)模型的特点,能够同时考察变量之间的短期和长期关系。假设我们收集了一段时间内的居民消费和可支配收入数据,通过对这些数据进行分析和估计,可以得到模型的参数估计值,从而揭示消费与收入之间的短期和长期关系。

a519573917的博客 6097

dlmalloc 图解

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34007886的博客 1331

(MATLAB)一维信号峰值检测findpeaks

一维信号波峰波谷检测,峰值、峰宽、到达时间计算。MATLAB自带的findpeaks函数能完成这一任务,在这里分享其基本用法与特殊用法。

HPC_ZY 2万+

dlmalloc 2.8.6 源码详解—[1]chunk

转载自:vector032 标记结构本章节将介绍基本的内存标记结构,包括chunk, tree chunk, sbin, tbin, segment, mstate等.这些重要的机构组成了dlmalloc分配算法的基础.2.1 chunkchunk是dlmalloc中最基本的一种结构,它代表了一块经过划分后被管理的内存单元. dlmalloc所有对内存的操作几乎都聚焦在chunk上.需要注意的是,

杏林小轩 1872

VASP实战:从非共线磁矩到自旋轨道耦合磁各向异性能的完整计算流程解析

本文详细解析了VASP中从非共线磁矩计算到自旋轨道耦合磁各向异性能的完整流程。通过实战案例和参数配置技巧,帮助研究者掌握非线性磁矩计算的关键步骤,包括SOC参数设置、文件传递逻辑以及磁各向异性能的精确提取方法,为材料磁性研究提供实用指导。

weixin_31102231的博客 411

SAP PS项目计划成本与预算设计:从概念到可用性控制详解

在项目管理中,成本计划与预算管控是决定项目成本能否受控的两个核心概念。成本计划反映“预计花费”,预算是“授权上限”,两者在WBS结构上既相互关联又彼此独立。SAP PS通过计划版本管理不同口径的估算,并借助可用性控制机制对采购申请、采购订单等业务操作进行事前拦截与提示,从而实现从“事后追认”到“事前控制”的转变。理解计划成本作为预算基线、预算作为控制阀门的原理,能够帮助实施顾问和项目管理者合理设计项目财务流程。在大型工程、研发或总包项目中,明确WBS层级、预算对象和检查规则,可有效避免超支风险。围绕SAP

weixin_33146151的博客 361

dlmalloc 2.8.6 源码详解(5)

本章节介绍dlmalloc的分配算法和实现. 由于存在多mspace的情况, dlmalloc使用了两套API. 一套对应默认的mspace, 以dl前缀开头, 如dlmalloc, dlrealloc等. 如果创建了自定义的mspace, 则使用mspace开头的API, 如mspace_malloc, mspace_realloc等. 但两套API在基础算法上是一致的. 我们就以默认的API为主要对象介绍.

vector03的专栏 3588

Origin绘制带差异显著性标记的分组均值条形图|科研论文图表教程(附数据格式模板)

传统柱状图虽能呈现组间均值差异,却隐藏个体数据分布;散点图虽能展示原始数据,却难以直观凸显统计显著性。带差异显著性(*)的分组均值条形图——它以“双层叙事”的创新设计,同时呈现群体特征与个体差异。

weixin_50236590的博客 1498

dlmalloc 2.8.6 源码详解(3)

本文章由vector03原创, 转载至 [vector03](https://blog.csdn.net/vector03/article/details/41008671)经过右移并与掩码计算的目的其实就是为了获得最高有效位的下一位。内存分配器设计中需要解决的两个重要问题就是空间和时间的矛盾。而后半部分一连串的计算其实就是判断是落在左边还是右边的分箱。的任意子树中根节点与其左右子树内的节点都没有明确的排序关系。号分箱则分别负责[2^9, 2^9+2^8)号分箱则负责[2^8+2^7, 2^9)

firebuffer的专栏 306

Experion PKS系列开发:I_O模块_ExperionPKS与第三方I-O模块的集成

通过上述步骤,可以成功将第三方I/O模块集成到Honeywell Experion PKS系统中,实现对现场设备的监视和控制。集成过程中需要注意选择合适的第三方模块,配置正确的通信参数,编写正确的控制逻辑,并进行充分的测试,以确保系统的稳定性和可靠性。不同的通信协议(如Modbus、Profibus、Ethernet/IP、CANopen、OPC UA)有其独特的配置和编程方法,但总体流程相似。在实际应用中,根据项目需求选择合适的协议和模块,可以有效提高系统的灵活性和适应性。

zhubeibei168的博客 1106

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

dlmalloc 2.8.6 源码详解(6)

本文章由vector03原创, 转载至[vector03](https://blog.csdn.net/vector03/article/details/41205355).小节中介绍了从系统申请的扩展内存会根据其首地址和旧区段之间的位置关系做合并。该函数会在一开始将分配请求从扩展空间中切割出来。这个代码基本上就是本小节开始时介绍的流程。这有些类似第一步中的扩展空间。中向系统获取内存的主要接口。将之前申请的空间归还给系统。对于无法合并的扩展内存区域。向系统申请一块适当的内存。这一步申请的结果是要归入。

firebuffer的专栏 261

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

内存分配器dlmalloc 2.8.3源码浅析

Android bionic使用dlmalloc进行内存分配, 遇到一些内存释放方面的issue, dvm heap也使用dlmalloc. 所以需要对dlmalloc有所了解. 转载此文. 本文对dlmalloc做了可谓详尽的分析, 一些细节还需要结合代码. 1. 本文档介绍 dlmalloc是目前一个十分流行的内存分配器,其由Doug Lea从1987年开始编写,到目前为止,最新版本为2.

zirconsdu的专栏 7792

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

dlmalloc 2.8.6 源码详解(4)

之所以需要额外引入这种数据结构是为了提升对非连续内存的管理能力。对某一大小内存的分配和释放都趋向于在一段时间里连续执行。从系统获取一定量内存后按照用户程序需求返回不同大小的。内存空间的整体分配能力和分配速度也获得了明显提升。这样其他人再来买同牌子的烟就继续从拆开的那条里取。如此全能的原因在于它位于内存空间的最顶端。其内部记录了关于内存分配的所有关键数据。这里使用的技术类似于操作系统中的就绪表。的初始状态与编译器的相关功能宏开关有关。小块内存如同人体血液中的坏胆固醇一样。此调用会根据传入的基址建立一个新的。

firebuffer的专栏 176

dlmalloc 2.8.6 源码详解(2)

本文章由vector03原创, 转载至[vector03](https://blog.csdn.net/vector03/article/details/40979181)这就保证了两种类型在基础结构上具有较好的兼容性。这个结构体中间填充多长的内容是没法确定的。的作用是将连续内存划分为一段段小的区块。将用户请求的内存值转化成实际的内部大小。与前者的区别在于管理上使用不同的结构。源码中定义了大量的宏来对其进行操作。的源码中有一幅用字符画成的示意图。在上一节的图中并没有画出对应的。

firebuffer的专栏 176

dlmalloc 2.8.6 源码详解—[0]基础知识

前述Dlmalloc是一个著名的内存分配器,最早由Doug Lea在1980s年代编写.由于早期C库的内置分配器在某种程度上的缺陷,因此dlmalloc出现后立即获得了广泛应用,足见其出色的表现.尽管时至今日, dlmalloc中的技术在一些地方已然落后于时代,很多优秀的allocator如google的tcmalloc, freeBSD的jemalloc等在某些情况下性能可以达到dlmalloc的

杏林小轩 3526
上一篇: 一个简单的实验,Java数组遍历
下一篇: dlmalloc 2.8.6 源码详解(2)
vector03
博客等级 码龄16年 62粉丝 16原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值