slab

#内存管理的艺术# 之 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)

#内存管理的艺术# 之 Nginx slab的实现 --- 第一篇“基本布局”

╄→гoц情女王★ 提交于 2020-03-01 04:14:33
访问 这里 ,获取更多原创内容。 说明:本系列的文章基于Nginx-1.5.0版本代码。 Nginx slab分配器用于管理和分配小于一页的内存申请,但实际上大于一页的内存分配也是统一实现的, 具体代码在core/ngx_slab.c文件中,对应的头文件是core/ngx_slab.h。 ngx_slab.h头文件中定义了两个重要的数据结构: ngx_slab_pool_t;/*整个内存区的管理结构*/ ngx_slab_page_t;/*用于表示page页内存管理单元和slot分级管理单元*/ 同时还声明了对外提供的几个函数原型,分别是: 用于初始化内存管理结构的: void ngx_slab_init(ngx_slab_pool_t *pool); 用于内存分配的: void *ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size); void *ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size); void *ngx_slab_calloc(ngx_slab_pool_t *pool, size_t size); void *ngx_slab_calloc_locked(ngx_slab_pool_t *pool, size_t size); /*alloc 和

Linux slab allocator and cache performance

回眸只為那壹抹淺笑 提交于 2019-12-23 22:05:15
问题 From the guide understanding linux kernel 3rd edition , chapter 8.2.10, Slab coloring- We know from Chapter 2 that the same hardware cache line maps many different blocks of RAM. In this chapter, we have also seen that objects of the same size end up being stored at the same offset within a cache. Objects that have the same offset within different slabs will, with a relatively high probability, end up mapped in the same cache line. The cache hardware might therefore waste memory cycles

Semantic Logging IsEnabled si always false?

与世无争的帅哥 提交于 2019-12-23 00:52:27
问题 I'm using SLAB out-of-process to log ETW events in my applications. Today I have a problem within WCF services hosted Under WcfTestClient.exe When I put breakpoint into WriteEvent methods of my EventSource inherited class, IsEnabled() return false !!! So no event is written to my console log out-of-process :( When starting my ConsoleEventSink, I can see my eventSource registered with a LogAlways level and None for MatchAnyKeyword property Any idea to check what is wrong for this problem ?

Rust语言实现的Slab内存管理器源码分析

泄露秘密 提交于 2019-12-10 05:49:25
Linux 所使用的 slab 分配器的基础是 Jeff Bonwick 为 SunOS 操作系统首次引入的一种算法。Jeff 的分配器是围绕对象缓存进行的。在内核中,会为有限的对象集(例如文件描述符和其他常见结构)分配大量内存。Jeff 发现对内核中普通对象进行初始化所需的时间超过了对其进行分配和释放所需的时间。因此他的结论是不应该将内存释放回一个全局的内存池,而是将内存保持为针对特定目而初始化的状态。 我们来看看rust中如何实现这一算法,也借此学习rust的应用技术。 源码: carllerche/slab :Preallocate memory for values of a given type. Slot结构(抽屉) 先来看一个基础数据结构Slot,这个数据结构对后面理解Slab至关重要。 enum Slot<T> { Empty(usize), Filled(T), Invalid, } 可以把Slot想象为一个抽屉,有三种状态: Empty 空抽屉,什么都没有装。Empty(usize) 一个带有编号的空抽屉。 Filled 装满的抽屉,Filled(T) 一个装了一个T类型对象的抽屉。 Invalid 无效的抽屉,这个抽屉当前处于无效状态。 一个Slot可以为空,可以无效,可以装一个T类型对象且只能装一个。 Slab结构(大柜子) 接着来看Slab数据结构

Memcached全面剖析

我只是一个虾纸丫 提交于 2019-12-03 00:37:58
整个网站应用中,缓存几乎无处不在,既存在于浏览器、也存在于应用服务器和数据库服务器;既可以对数据缓存(分布式缓存),也可以对文件缓存(分布式存储系统),还可以对页面片段缓存(ESI)。 一、合理使用缓存 1.频繁修改的数据 缓存主要存放读写比很高、很少变化的数据。一般说来,数据的读写比在2:1以上,如商品类目信息、热门搜索列表信息等。 2.没有热点的数据 如果应用系统访问数据没有热点,不遵循二八定律,即大部分数据并没有集中在小部分数据上,那么缓存就没有意义。 3.数据不一致与脏读 一般会对还存的数据设置失效时间,一旦超过失效时间,就会从数据库重新加载,因此应用要容忍一定时间的数据不一致。 4.缓存可用性 为了应对当缓存服务崩溃时,数据库会因为完全不能承受如此大的压力而宕机,进而导致整个网站不可用(缓存雪崩故障),可以通过 缓存热备 或者 分布式缓存服务器集群 来改善缓存的可用性。 5.缓存预热 可以在缓存系统启动时就把热点数据加载好,这个缓存预加载手段叫作缓存预热。常用于元数据如城市地名列表、类目信息等。 6.缓存穿透 如果因为不恰当的业务、或者恶意攻击持续高并发地请求某个不存在的数据,由于缓存没有保存该数据,所有请求都会落到数据库上,会对数据库造成很大压力,甚至崩溃。 一个简单的对策就是将不存在的数据也缓存起来(value为null)。 二、Memcached高效的内存管理

SLAB, out-of-process: changing the signature of an event source method causes incorrect event logging

二次信任 提交于 2019-12-01 09:52:02
问题 I implemented an event source class for logging events. After repeatedly changing the signature (parameters names and parameters types) of one method that logs events, the events are no longer correctly logged. For instance when an event is logged, instead of setting the Payload with the current parameters name, the events are logged using the parameters used for the previous version of the method. Eg: Version n of the method: [Event(5, Message = "Action: {0}", Task = Tasks.PAGE, Keywords =