内存管理

Redis 内存管理 源码分析

拥有回忆 提交于 2019-11-27 10:34:18
要想了解redis底层的内存管理是如何进行的,直接看源码绝对是一个很好的选择 下面是我添加了详细注释的源码,需要注意的是,为了便于源码分析,我把redis为了弥补平台差异的那部分代码删了,只需要知道有这个东西便好 下面我会贴上两份源码:一份是我自己的,有删减添加了注释的,一部分是原生的,可以做个参考对照 redis内存管理部分的源码在 zmalloc.h文件和zmalloc.c文件 推荐文章: https://www.cnblogs.com/likui360/p/5272443.html https://www.cnblogs.com/likui360/p/5272975.html http://wiki.jikexueyuan.com/project/redis/memory-data-management.html 我的源码 zmalloc.h: #ifndef __ZMALLOC_H #define __ZMALLOC_H #define __xstr(s) __str(s) #define __str(s) #s #ifndef ZMALLOC_LIB #define ZMALLOC_LIB "libc" #endif /* CPU一次性能读取数据的二进制位数称为字长,也就是我们通常所说的32位系统(字长4个字节)、64位系统(字长8个字节)的由来。 所谓的8字节对齐

内存管理机制与垃圾回收机制

☆樱花仙子☆ 提交于 2019-11-27 08:32:53
内存管理机制 栈(Stack)是一种后进先出(FILO)的数据结构 一些变量和形参都存在栈中 栈中存一些简单的值类型数据 在运行时栈是可以随时更新的 当变量超出自身的作用于时 自动从栈中弹出 栈的元素是连续的 不会产生一些碎片垃圾 所以栈是不需要GC机制来回收栈中的数据的 堆(Heap)堆没有栈的特性 没有后进先出的顺序 堆像是个大容器 存储相对复杂的数据类型(比如引用类型)以及解决栈中出现栈溢出的问题 堆内存中存放数据是无序的 可理解为随机存放 数据之间连续不起来 所以堆中容易出现碎片垃圾 这时可以对数据加Dirty脏标记 方便记录数据 需要对数据进行排序 排序后即可清除多余的碎片垃圾 静态区 静态区主要存放程序中所有的全局变量和静态变量 程序运行后 静态区的内存要等到程序结束才释放 垃圾回收机制 GC(GarbageCollect)GC主要是回收堆上的数据资源 栈中的数据超出作用域会自动出栈不用堆来处理 垃圾回收时是判断gameObject是否还有有效的引用 如果gameobject为null那么GC认为他是垃圾 通过算法回收无效引用资源 当然也不是回收直接清除 是积累到一定量之后启动垃圾回收机主 GC回收实际上是调用了析构函数(~函数名()) 来源: https://blog.csdn.net/PJ_Mr_Zhang/article/details/99609567

内存管理机制与垃圾回收机制

旧巷老猫 提交于 2019-11-27 08:32:42
内存管理机制 栈(Stack)是一种后进先出(FILO)的数据结构 一些变量和形参都存在栈中 栈中存一些简单的值类型数据 在运行时栈是可以随时更新的 当变量超出自身的作用于时 自动从栈中弹出 栈的元素是连续的 不会产生一些碎片垃圾 所以栈是不需要GC机制来回收栈中的数据的 堆(Heap)堆没有栈的特性 没有后进先出的顺序 堆像是个大容器 存储相对复杂的数据类型(比如引用类型)以及解决栈中出现栈溢出的问题 堆内存中存放数据是无序的 可理解为随机存放 数据之间连续不起来 所以堆中容易出现碎片垃圾 这时可以对数据加Dirty脏标记 方便记录数据 需要对数据进行排序 排序后即可清除多余的碎片垃圾 静态区 静态区主要存放程序中所有的全局变量和静态变量 程序运行后 静态区的内存要等到程序结束才释放 垃圾回收机制 GC(GarbageCollect)GC主要是回收堆上的数据资源 栈中的数据超出作用域会自动出栈不用堆来处理 垃圾回收时是判断gameObject是否还有有效的引用 如果gameobject为null那么GC认为他是垃圾 通过算法回收无效引用资源 当然也不是回收直接清除 是积累到一定量之后启动垃圾回收机主 GC回收实际上是调用了析构函数(~函数名()) 来源: https://www.cnblogs.com/PJ-Mr-Zhang/p/11354647.html

内存管理之栈stack

喜你入骨 提交于 2019-11-27 07:53:36
1、什么是栈 栈是一种数据结构,C语言中使用栈来保存局部变量。栈是被发明出来管理内存的。 2、栈管理内存的特点(小内存、自动化) 先进后出 FILO first in last out 栈 先进先出 FIFO first in first out 队列 栈的特点就是入口就是出口,只有一个口,另一个口是堵死的。所以先进来的必须后出去。 队列的特点就是入口和出口都有,必须从入口进去,从出口出来。所以先进来的必须先出去,不然就会堵住后边的。 3、栈的应用举例:局部变量 C语言中的局部变量是用栈来实现的。 我们在C语言中定义一个局部变量时(int a),编译器就会在栈中分配一段空间(4字节)给我们局部变量使用(分配时 栈顶指针会移动给出空间,给局部变量a使用的意思就是,将4个字节的栈内存的内存地址和我们定义的局部变量名a给关联 起来),对应栈的操作就是入栈。 注意:这里栈指针的移动和内存分配是自动的(栈自己完成,不用我们写代码去操作)。 然后等我们函数退出的时候,局部变量要灭亡。对应栈的操作就是弹栈(出栈)。出栈时也是栈顶指针移动将栈空间中 与a关联的那4个字节空间释放。 这个动作也是栈自动完成的,也不用人写代码干预。 栈的优点:栈管理内存,好处是方便,分配和最后回收都不用程序员操心,C语言自动完成。 分析一个细节:C语言中,定义局部变量如果没有初始化,则值是随机的,为什么?

chrome内存管理

依然范特西╮ 提交于 2019-11-27 06:25:59
前提 这里的标准内存申请释放指的是语言本身使用的malloc、free、calloc、new、delete等。 平台windows 7. 其他平台得绕道了- -!。 热身 使标准库的malloc、free等函数调用我们自己的实现通常有两种方法,一种,iat hook等形式,另外一种就是替换标准库为新实现。 第一种实现估计是老生常谈了,没啥新颖的,但是会杀毒软件等当为病毒等玩意儿干,狗拿耗子啊。 第二种方法,在没有看过chrome的allocator工程的具体实现之前或者说没看过prep_libc.py这个脚本以前,一直都没有这个概念,又一次感觉弱爆了。 技术要点 其实第二种说白了也很简单,实现就是通过visual studio 提供lib命令,将库里面的默认malloc等实现给移除。链接库的时候,使用新的libcmt.lib进行链接即可。由于是已经将malloc等函数给移除了,所以这时就需要自己实现一份就行了,然后链接,不会出现二义性。世界变得又美好了。 这份新实现的malloc等函数就可以任意的实现了(chrome中在base/allocator/allocator_shim.cc中)。如:chrome用tcmalloc等来替换原生的内存申请函数。至于tcmalloc的性能什么的自行google。 来一段内存申请的函数瞧瞧 就一堆宏了,说到底都交给tcmalloc去干苦力去

程序运行为什么需要内存

柔情痞子 提交于 2019-11-27 04:54:42
1、计算机程序运行过程   计算机程序运行的过程,其实就是程序中很多函数相继运行的过程。程序是由很多函数组成的,程序的本质就是函数,函数的本质就是加工数据的动作。 2、冯诺依曼结构和哈佛结构 (1)、冯诺依曼结构:数据和代码放在一起 (2)、哈佛结构:数据和代码分开存放 (3)、什么是代码:函数 (4)、什么是数据:全局变量、局部变量 在运行操作系统的片子中,运行应用程序时:这时候所有的应用程序的代码和数据都在DRAM中,所以这种结构就是冯诺依曼结构; 在单片机中,我们把程序代码烧写到Flash(NorFlash)中,然后程序在flash中原地运行,程序中涉及到的数据(全局变量、局部变量)不能放在flash中,必须放在RAM(SRAM)中.这就是哈佛结构。 3、动态内存DRAM和静态内存SRAM 4、为什么需要内存 ? 内存是用来存储可变数据的,数据在程序中就会表现为全局变量和静态变量(在gcc中,其实常量也是存储在内存中的)(大部分单片机中,常量是存储在flash中,也就是代码段)。所以内存对我们写程序来说是非常重要的,对于程序运行也很重要 所以说内存对于程序来说,可以说是本质需求。程序越简单,需要的内存越少,程序越复杂,需要的内存越大。所以内存管理对于写程序是很重要的。比如说:数据结构(研究数据如何组织)、算法(算法是为了用更有效的方法来加工数据) 5、如何管理内存 (1)

oc-内存管理 - 探路篇

瘦欲@ 提交于 2019-11-27 03:44:17
一、过程: 生成对象 -> alloc 持有对象 -> retain 释放对象 -> release 废弃对象:所有引用都释放 -> dealloc 二、MRC:需要手动释放自己持有的对象 [参考资料]: http://www.open-open.com/lib/view/open1460693431491.html NSObject负责内存管理 非自己生成的对象通过retain方法实现持有对象。 id obj = [NSArray array]; // 取得非自己生成并持有的对象 [obj retain]; 调用autorelease后,对象不会被立即释放,而是注册到autoreleasepool中,知道pool结束,对象才被释放。 ⚠️无法释放非自己持有的对象,但可持有非自己生成的对象。 三、ARC:自动释放自己持有的对象 释放方式: 1、赋其他值 2、超出作用域 所有权修饰符 _ _strong id类型和对象类型默认 在超出变量作用域后被释放 _ _weak 解决循环引用问题(易发生互相强引用) 当引用计数为0时,自动赋值nil 必须是oc对象(assign可以非oc对象) weak被赋以一个非自己生成的对象,weak并不会立即释放,而是注册到AutoreleasePool中,延长生命周期。 不持有对象 ⚠️与assign的区别 assign是指针赋值,不对引用计数操作

Android内存管理、监测剖析

喜欢而已 提交于 2019-11-27 02:03:58
Android内存管理机制 Android内存管理主要有:LowMemory Killer机制,Ashmem,PMEM/ION及Native内存和Dalvik内存管理管理和JVM垃圾回收机制。 LowMemory Killer机制 源码位置drivers/staging/Android/lowmemorykiller.c Android是一个多任务系统,也就是说可以同时运行多个程序,这个大家应该很熟悉。一般来说,启动运行一个程序是有一定的时间开销的,因此为了 加快运行速度,当你退出一个程序时,Android并不会立即杀掉它,这样下次再运行该程序时,可以很快的启动。随着系统中保留的程序越来越多,内存肯定 会出现不足,low memory killer就是在系统内存低于某值时,清除相关的程序,保障系统保持拥有一定数量的空闲内存。 Low memorykiller根据两个原则,进程的重要性和释放这个进程可获取的空闲内存数量,来决定释放的进程。 进程的重要性,由task_struct->signal_struct->oom_adj决定, Android将程序的重要性分成以下几类,按照重要性依次降低的顺序,每个程序都会有一个oom_adj值,这个值越小,程序越重要,被杀的可能性越低: 除了上述程序重要性分类之外,Android系统还维护着另外一张表minfree用于维护内存警戒值

【C++沉思录】代理类

不打扰是莪最后的温柔 提交于 2019-11-27 01:31:41
1、考虑下面的场景:设计一个容器,包含一组类型不同但相互关联的对象(比如:Animal,Dog,Cat),对象具备多态行为。 2、容器一般只能包含一种类型的对象,使用vector<Animal> 会造成对象切割,不具备多态行为。 3、经典的解决办法是:vector<Animal*>, 但是这会增加内存管理的负担。考虑下面的情况: Dog d; vec[i] = &d; // 局部对象d销毁, vec[i] 指向垃圾 vec[i] = vec[j]; // 指向同一个对象, 在vec析构之前,需要手动遍历vec,进行delete,两个delete同一个对象,行为未定义。 4、怎么解决上面的问题,每次都创建一个新的对象。如下: Dog d; vec[i] = new Dog(d); vec[i] = new Animal(vec[j]); // 这里存在问题,由于vec[j] 类型未知,只能使用Animal,但是这造成对象切割。 5、处理编译时类型未知的对象,使用虚方法。Animal 增加一个纯虚方法clone,纯虚方法导致Animal成为一个抽象类, 不能实例化,同时要求子类必须重写clone方法。注:Animal 可以提供纯虚方法clone的实现。 6、Animal* pa = new Dog; delete pa; 为了能够调用Dog的析构方法,定义Animal的析构方法是虚方法

OC语言自学《十一》---- OC(内存管理知识总结)

跟風遠走 提交于 2019-11-27 00:09:31
一、 retain、release retain方法给对象的引用计数器+1 release方法给对象的引用计数器-1 retain方法会返回对象本身,release方法没有返回值 dealloc方法 当一个对象要被回收的时候会被调用 重写的时候,一定要调用[super dealloc]方法,这句调用一定要放到最后面 空指针 OC中没有空指针异常 没有指向任何东西的指针(存储的东西是nil、NULL、0),给空指针发送消息不会报错 野指针 指向僵尸对象(不可用的内存)的指针,给野指针发送消息会报错(EXC_BAD_ACCESS) 僵尸对象 所占用内存已经被回收的对象,僵尸对象不能再使用 二、retain、release使用注意 谁retain,谁release 只要你调用了retain,无论这个对象是如何生成的,你都要调用release 有始有终,有加就有减 曾经让对象的计数器+1,就必须在最后让对象计数器-1 如果你通过alloc、new或[mutable]copy来创建一个对象,那么你必须调用release或autorelease 你想使用某个对象,就应该让对象的计数器+1(让对象做一次retain操作) 当你不想在使用某个对象时,我们就该让对象的计数器-1(让对象做一次release操作) 谁retain,谁就release 谁alloc,谁就release 三