内存管理

python面试1000题之7-8

你离开我真会死。 提交于 2020-03-02 18:52:15
7 Python是如何进行内存管理的? http://developer.51cto.com/art/201007/213585.htm Python引用了一个内存池(memory pool)机制,即Pymalloc机制(malloc:n.分配内存),用于管理对小块内存的申请和释放 内存池(memory pool)的概念: 当 创建大量消耗小内存的对象时,频繁调用new/malloc会导致大量的内存碎片,致使效率降低。内存池的概念就是预先在内存中申请一定数量的,大小相等 的内存块留作备用,当有新的内存需求时,就先从内存池中分配内存给这个需求,不够了之后再申请新的内存。这样做最显著的优势就是能够减少内存碎片,提升效率。 内存池的实现方式有很多,性能和适用范围也不一样。 python中的内存管理机制——Pymalloc: python中的内存管理机制都有两套实现,一套是针对小对象,就是大小小于256bits时,pymalloc会在内存池中申请内存空间;当大于256bits,则会直接执行new/malloc的行为来申请内存空间。 关于释放内存方面,当一个对象的引用计数变为0时,python就会调用它的析构函数。在析构时,也采用了内存池机制,从内存池来的内存会被归还到内存池中,以避免频繁地释放动作。 8 解释一下python的and-or语法 http://www.kuqin.com

虚拟地址和物理地址及其映射

你离开我真会死。 提交于 2020-03-02 17:42:41
前一段时间在面试总监的时候,总监问了我这样的一个问题:你个我说说物理内存和虚拟内存到底是怎么一回事? 其实之前我看过这个问题,据我理解的,当时是这么回答的“进程在运行的时候,操作系统都为其分配一个4GB的地址空间,即所谓的虚拟地址空间,一般情况下,当我们的程序很大的时候,实际的物理内存根本不能满足我们的需求的时候,这个时候操作系统就会借助磁盘空间来做虚拟的内存空间,把当前进程不需要的数据放在磁盘上,等到用到的时候,在利用调度算法把所需要的数据从磁盘空间上调度到内存,虚拟内存就是为了扩大内存的容量,每当我们要运行一个程序的时候经过编译以后形成的仅仅是逻辑上的空间,根本不是可以直接运行的内存空间,所以它还存在一个地址映射的概念。”当时感觉回答的很是笼统,只见总监在最后说了一句,你下去还是把这一块的内容在好好看看,所以今天就好好的把这个概念理一理。 首先我从最基本的概念说起,什么是物理内存的概念,虚拟内存的概念? 物理内存,在应用中,自然是顾名思义,物理上,真实的插在板子上的内存是多大就是多大了。而在CPU中的概念,物理内存就是CPU的地址线可以直接进行寻址的内存空间大小。比如8086只有20根地址线,那么它的寻址空间就是1MB,我们就说8086能支持1MB的物理内存,及时我们安装了128M的内存条在板子上,我们也只能说8086拥有1MB的物理内存空间

slab内存管理分享

孤街浪徒 提交于 2020-03-02 16:45:35
1. 什么是 slab Slab 是中内存管理算法,最早是由 sun 的工程师提出,主要是基于一下因数考虑: 1 :内核函数经常倾向于反复请求相同的数据类型。比如:创建进程时,会请求一块内存来存放 mm 结构。 2 :不同的结构使用不同的分配方法可以提高效率。同样,如果进程在撤消的时候,内核不把 mm 结构释放掉,而是存放到一个缓冲区里,以后若有请求 mm 存储空间的行为就可以直接从缓冲区中取得,而不需重新分配内存 . 3: 前面我们曾分析过,如果伙伴系统频繁分配,释放内存会影响系统的效率,以此,可以把要释放到的内存放到缓冲区中,直至超过一个阀值才把它释放至伙伴系统,这样可以在一定程度上缓减减伙伴系统的压力 4: 为了缓减“内碎片”的产生,通常可以把小内存块按照 2 的倍数组织在一起,这一点和伙伴系统类似 2.slab 算法的具体思想 slab 的思想是将 内存分成大小不等的 slabs chunks (先分成大小相等的 slabs ,然后每个 slab 被分成大小相等 chunks ,不同 slab 的 chunk 大小是不相等的 )。 chunk 的大小依次从一个最小数开始,按某个因子增长,直到达到最大的可能值。 如果最小值为 400B ,最大值是 1MB ,因子是 1.20 ,各个 slab 的 chunk 的大小依次是: slab1 - 400B slab2 - 480B

#内存管理的艺术# 之 Nginx slab的实现 --- 第五篇“基于页的内存释放”

孤者浪人 提交于 2020-03-02 15:34:28
访问 这里 ,获取更多原创内容。 说明:本系列的文章基于Nginx-1.5.0版本代码。 在 上一篇 ”基于块的内存释放“中,我们已经见过一个函数: static void ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page, ngx_uint_t pages); 单从名字应该就已经能够猜到这个函数的作用了,没错,就是本篇的主题 --- ”基于页的内存释放“,当释放的内存类型为”NGX_SLAB_PAGE “,或者与待释放的内存块所对应的页已经完全释放时,就到了这个函数大显身手的时候了,但它的内容却只有短短的十几行代码: static void ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page, ngx_uint_t pages) { ngx_slab_page_t *prev; page->slab = pages--; /*如果待释放的内存空间不止一页,则需要将后续的页管理单元恢复为初始化状态*/ if (pages) { ngx_memzero(&page[1], pages * sizeof(ngx_slab_page_t)); } /*根据前面几篇的内容可以知道,当页内存管理单元挂接在slot分级链表下时,page-

#内存管理的艺术# 之 Nginx slab的实现 --- 第四篇“基于块的内存释放”

人盡茶涼 提交于 2020-03-02 15:26:25
访问 这里 ,获取更多原创内容。 说明:本系列的文章基于Nginx-1.5.0版本代码。 本篇开始将涉及到Nginx slab内存管理中与内存释放相关的内容,紧跟 上一篇 的步伐,趁热打铁,就从“基于块的内存释放”开始吧。 开门见源码: void ngx_slab_free(ngx_slab_pool_t *pool, void *p) { ngx_shmtx_lock(&pool->mutex); ngx_slab_free_locked(pool, p); ngx_shmtx_unlock(&pool->mutex); } void ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p) { size_t size; uintptr_t slab, m, *bitmap; ngx_uint_t n, type, slot, shift, map; ngx_slab_page_t *slots, *page; ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p); /*判断待释放的地址是否在合法的内存空间中*/ if ((u_char *) p < pool->start || (u_char *) p > pool->end) {

#内存管理的艺术# 之 Nginx slab的实现 --- 第三篇“基于块的内存分配”

放肆的年华 提交于 2020-03-02 15:15:48
访问 这里 ,获取更多原创内容。 说明:本系列的文章基于Nginx-1.5.0版本代码。 在“ 基本布局 ”一篇中我们曾经介绍过,ngx_slab.c的实现中将内存的分配分为了两个大类,除了上一篇讲的“ 基于页的内存分配 ”外,另一类就是本篇中要介绍的“基于块的内存分配”了。 为了能够满足对小块内存的申请需求,Nginx slab分配器将页划分为更小的块(chunk),并引入了“slot分级内存管理数组”来与“page页内存管理数组”一起完成对小块内存的分配和释放流程的管理。 根据“ 基本布局” 一篇中的内容可以知道,Nginx slab分配器是按2的幂次大小来进行分级的: Nginx slab分配器的分级结构图 当最小块大小(min_size)为8bytes,页大小(pagesize)为4096bytes时,分级数为: pagesize_shift - min_shift = 9 即对应ngx_slab_init()中的n为9,也就是说slot分级管理数组中有9个元素,我们后面的讨论都是基于这个模型来进行的。 在上面的“Nginx slab分配器的分级结构图”中我们还看到了两个比较陌生的变量:ngx_slab_exact_shift(7) 和 ngx_slab_exact_size(128),这两个值分别代表什么含义,又是怎么得到的呢? 前面说过

#内存管理的艺术# 之 Nginx slab的实现 --- 第二篇“基于页的内存分配”

梦想的初衷 提交于 2020-03-02 14:04:28
访问 这里 ,获取更多原创内容。 说明:本系列的文章基于Nginx-1.5.0版本代码。 在 上一篇 中已经介绍了Nginx slab分配器的基本原理和内存空间布局,现在我们将在此基础上引入“基于页的内存分配”的相关内容。之所以这样安排是因为它的实现相对于“基于块的内存分配”要简单许多,同时它又是“基于块的内存分配”的基础,以它为突破口怎么看都是最好的选择:) 在”基于页的内存分配“流程中只需要用到”page页内存管理单元“,而不涉及”分级内存管理单元“,为了方便讨论,我们将初始化后的内存布局图简化如下: 一、内存的分配 Nginx slab本身没有对外提供专门的按页分配内存的接口,具体采用哪种分配方式是在内部根据传入的size值并结合一定的算法来进行决策的。以ngx_slab_alloc为例: void * ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size) { void *p; ngx_shmtx_lock(&pool->mutex); p = ngx_slab_alloc_locked(pool, size); ngx_shmtx_unlock(&pool->mutex); return p; } void * ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)

(六)boost库之内存管理shared_ptr

安稳与你 提交于 2020-03-01 23:45:22
1、shared_ptr的基本用法 boost::shared_ptr< int > sp( new int (10)); //一个指向整数的shared_ptr assert(sp.unique()); //现在shared_ptr是指针的唯一持有者 boost::shared_ptr< int > sp2 = sp; //第二个shared_ptr,拷贝构造函数 assert(sp == sp2 && sp.use_count() == 2); //两个shared_ptr相等,指向同一个对象,引用计数为2 *sp2 = 100; //使用解引用操作符修改被指对象 assert(*sp == 100); //另一个shared_ptr也同时被修改 sp.reset(); //停止shared_ptr的使用,引用计数减一 assert(!sp); //sp不再持有任何指针(空指针) assert(sp2.use_count() == 1); //sp2引用计数变为1 sp.reset( new int (20)); //sp管理一个新对象 assert(*sp == 20); 2、应用于标准容器 有两种方式可以将shared_ptr应用于标准容器(或者容器适配器等其他容器)。 一种用法是将容器作为shared_ptr管理的对象,如shared_ptr<list<T> >

06.进程的虚拟内存管理.md

牧云@^-^@ 提交于 2020-03-01 22:15:45
正好遇到 华庭(庄命强)的glibc内存管理Ptmalloc2 源代码分析 一文,非常开心。真是大佬。我只是借着这篇文章稍微整理一下,为了以后自己回顾的时候能够更好的排查问题。 6.1 linux进程内存布局 x86 平台 Linux 进程内存布局   Linux 系统在装载 elf 格式的程序文件时,会调用 loader 把可执行文件中的各个段依次 载入到从某一地址开始的空间中(载入地址取决 link editor(ld)和机器地址位数,在 32 位机 器上是 0x8048000,即 128M 处)。如下图所示,以 32 位机器为例,首先被载入的是.text 段, 然后是.data 段,最后是.bss 段。这可以看作是程序的开始空间。程序所能访问的最后的地 址是 0xbfffffff,也就是到 3G 地址处,3G 以上的 1G 空间是内核使用的,应用程序不可以直 接访问。  &emsp应用程序的堆栈从最高地址处开始向下生长,.bss 段与堆栈之间的空间是空闲的, 空闲空间被分成两部分,一部分为 heap,一部分为 mmap 映射区域,mmap 映射区域一般 从 TASK_SIZE/3 的地方开始,但在不同的 Linux 内核和机器上,mmap 区域的开始位置一般是 不同的。Heap 和 mmap 区域都可以供用户自由使用,但是它在刚开始的时候并没有映射到 内存空间内,是不可访问的

8.动态内存管理malloc calloc realloc free

半世苍凉 提交于 2020-03-01 21:24:36
malloc 描述 C 库函数 void *malloc(size_t size) 分配所需的内存空间,并返回一个指向它的指针。 声明 下面是 malloc() 函数的声明。 void *malloc(size_t size) 参数 size – 内存块的大小,以字节为单位。 返回值 该函数返回一个指针 ,指向已分配大小的内存。如果请求失败,则返回 NULL。 realloc 描述 C 库函数 void *realloc(void *ptr, size_t size) 尝试重新调整之前调用 malloc 或 calloc 所分配的 ptr 所指向的内存块的大小。 声明 下面是 realloc() 函数的声明。 void *realloc(void *ptr, size_t size) 参数 ptr – 指针指向一个要重新分配内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针。 size – 内存块的新的大小,以字节为单位。如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针。 返回值 该函数返回一个指针 ,指向重新分配大小的内存。如果请求失败,则返回 NULL。 calloc 描述 C 库函数 void