参考 http://www.cnblogs.com/justfortaste/p/3198406.html

http://m.blog.csdn.net/blog/IT_PCode/17007833

http://blog.chinaunix.net/uid-28364803-id-3419777.html

http://blog.chinaunix.net/uid-26896862-id-3412033.html

mysql数据库分mysql层和存储引擎层,每个层都有各自的分配内存方法

mysql层分配内存方法比较简单

当一个请求过来后,使用一个线程为其服务,mysql层为它分配内存

mysql层mem_root

  1. typedef struct st_used_mem
  2. { /* struct for once_alloc (block) */
  3. struct st_used_mem *next; /* Next block in use */
  4. unsigned int left; /* memory left in block */
  5. unsigned int size; /* size of block */
  6. } USED_MEM;
  7.  
  8. typedef struct st_mem_root
  9. {
  10. USED_MEM *free; /* blocks with free memory in it */
  11. USED_MEM *used; /* blocks almost without free memory */
  12. USED_MEM *pre_alloc; /* preallocated block */
  13. /* if block have less memory it will be put in 'used' list */
  14. size_t min_malloc;
  15. size_t block_size; /* initial block size */
  16. unsigned int block_num; /* allocated blocks counter */
  17. /*
  18. first free block in queue test counter (if it exceed
  19. MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list)
  20. */
  21. unsigned int first_block_usage;
  22.  
  23. void (*error_handler)(void);
  24. } MEM_ROOT;
  1. mysql内存池
  2. mysql内部使用的内存管理程序,可以实现多次申请内存块, 中途任何时刻失败, 或者下次使用前释放内存, 无需再关心每次申请和释放了哪些内存.
  3. 工作原理:
  4. 初始化定义每次分配的最小内存块大小M,如果申请一次内存, 大小为X, X大于M, 就分配一块X的内存, 加入到管理链表中.如果小于的话, 看之前剩余的还够不够, 如果足够的话, 返回之前多余的内存地址.如果不够,则申请这么大的内存, 也计入链表中。
  5. 释放是一次性的,也可以不释放内存,而是标记已经使用的内存为“未使用”,下次同样的应用可以继续使用。
  6. 创建内存池
  7. /*
  8. Initialize memory root
  9.  
  10. SYNOPSIS
  11. init_alloc_root()
  12. mem_root - memory root to initialize
  13. block_size - size of chunks (blocks) used for memory allocation
  14. (It is external size of chunk i.e. it should include
  15. memory required for internal structures, thus it
  16. should be no less than ALLOC_ROOT_MIN_BLOCK_SIZE)
  17. pre_alloc_size - if non-0, then size of block that should be
  18. pre-allocated during memory root initialization.
  19.  
  20. DESCRIPTION
  21. This function prepares memory root for further use, sets initial size of
  22. chunk for memory allocation and pre-allocates first block if specified.
  23. Altough error can happen during execution of this function if
  24. pre_alloc_size is non-0 it won't be reported. Instead it will be
  25. reported as error in first alloc_root() on this memory root.
  26. */
  27.  
  28. void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
  29. uint pre_alloc_size __attribute__((unused))) {
  30. DBUG_ENTER("init_alloc_root");
  31. mem_root->free = mem_root->used = mem_root->pre_alloc = ;
  32. mem_root->min_malloc = ;
  33. mem_root->block_size = block_size - ALLOC_ROOT_MIN_BLOCK_SIZE;
  34. mem_root->error_handler = ;
  35. mem_root->block_num = ; /* We shift this with >>2 */
  36. mem_root->first_block_usage = ;
  37.  
  38. if (pre_alloc_size) {
  39. if ((mem_root->free = mem_root->pre_alloc = (USED_MEM*) my_malloc(
  40. pre_alloc_size + ALIGN_SIZE(sizeof(USED_MEM)),
  41. MYF())))
  42. {
  43. mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
  44. mem_root->free->left= pre_alloc_size;
  45. mem_root->free->next= ;
  46. }
  47. }
  48.  
  49. DBUG_VOID_RETURN;
  50. }
  51. 申请内存
  52. gptr alloc_root(MEM_ROOT *mem_root, unsigned int Size) {
  53. uint get_size, block_size;
  54. gptr point;
  55. reg1 USED_MEM *next = ;
  56. reg2 USED_MEM **prev;
  57. DBUG_ENTER("alloc_root");DBUG_ASSERT(alloc_root_inited(mem_root));
  58.  
  59. Size = ALIGN_SIZE(Size);
  60. if ((*(prev = &mem_root->free)) != NULL)
  61. {
  62. if ((*prev)->left < Size
  63. && mem_root->first_block_usage++
  64. >= ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP
  65. && (*prev)->left < ALLOC_MAX_BLOCK_TO_DROP)
  66. {
  67. next = *prev;
  68. *prev = next->next; /* Remove block from list */
  69. next->next = mem_root->used;
  70. mem_root->used = next;
  71. mem_root->first_block_usage = ;
  72. }
  73. for (next = *prev; next && next->left < Size; next = next->next)
  74. prev = &next->next;
  75. }
  76. if (!next) { /* Time to alloc new block */
  77. block_size = mem_root->block_size * (mem_root->block_num >> );
  78. get_size = Size + ALIGN_SIZE(sizeof(USED_MEM));
  79. get_size = max(get_size, block_size);
  80.  
  81. if (!(next = (USED_MEM*) my_malloc(get_size, MYF(MY_WME)))) {
  82. if (mem_root->error_handler)
  83. (*mem_root->error_handler)();
  84. return ((gptr) ); /* purecov: inspected */
  85. }
  86. mem_root->block_num++;
  87. next->next = *prev;
  88. next->size = get_size;
  89. next->left = get_size - ALIGN_SIZE(sizeof(USED_MEM));
  90. *prev = next;
  91. }
  92.  
  93. point = (gptr) ((char*) next + (next->size - next->left));
  94. /*TODO: next part may be unneded due to mem_root->first_block_usage counter*/
  95. if ((next->left -= Size) < mem_root->min_malloc) { /* Full block */
  96. *prev = next->next; /* Remove block from list */
  97. next->next = mem_root->used;
  98. mem_root->used = next;
  99. mem_root->first_block_usage = ;
  100. }DBUG_RETURN(point);
  101. }
  102. 释放内存
  103. /*
  104. Deallocate everything used by alloc_root or just move
  105. used blocks to free list if called with MY_USED_TO_FREE
  106.  
  107. SYNOPSIS
  108. free_root()
  109. root Memory root
  110. MyFlags Flags for what should be freed:
  111.  
  112. MY_MARK_BLOCKS_FREED Don't free blocks, just mark them free
  113. MY_KEEP_PREALLOC If this is not set, then free also the
  114. preallocated block
  115.  
  116. NOTES
  117. One can call this function either with root block initialised with
  118. init_alloc_root() or with a bzero()-ed block.
  119. It's also safe to call this multiple times with the same mem_root.
  120. */
  121.  
  122. void free_root(MEM_ROOT *root, myf MyFlags) {
  123. reg1 USED_MEM *next, *old;
  124. DBUG_ENTER("free_root");
  125.  
  126. if (!root) /* QQ: Should be deleted */
  127. DBUG_VOID_RETURN; /* purecov: inspected */
  128. if (MyFlags & MY_MARK_BLOCKS_FREE)
  129. {
  130. mark_blocks_free(root);
  131. DBUG_VOID_RETURN;
  132. }
  133. if (!(MyFlags & MY_KEEP_PREALLOC))
  134. root->pre_alloc = ;
  135.  
  136. for (next = root->used; next;) {
  137. old = next;
  138. next = next->next;
  139. if (old != root->pre_alloc)
  140. my_free((gptr) old, MYF());
  141. }
  142. for (next = root->free; next;) {
  143. old = next;
  144. next = next->next;
  145. if (old != root->pre_alloc)
  146. my_free((gptr) old, MYF());
  147. }
  148. root->used = root->free = ;
  149. if (root->pre_alloc) {
  150. root->free = root->pre_alloc;
  151. root->free->left = root->pre_alloc->size - ALIGN_SIZE(sizeof(USED_MEM));
  152. TRASH_MEM(root->pre_alloc);
  153. root->free->next = ;
  154. }
  155. root->block_num = ;
  156. root->first_block_usage = ;
  157. DBUG_VOID_RETURN;
  158. }
  159. 内存池使用实例
  160. void test_myalloc() {
  161. MEM_ROOT root;
  162. char *str;
  163. init_alloc_root(&root, << , << );
  164. str = (char *) alloc_root(&root, * sizeof(double));
  165. if (NULL == str)
  166. printf("cannot get memory for alloc root for str\n");
  167. strcpy(str, "hello\n");
  168. puts(str);
  169. //mark free, can be used again
  170. free_root(&root, MY_MARK_BLOCKS_FREE);
  171. //free, can not be used
  172. free_root(&root, );
  173. }
  1. void my_free(void *ptr)
  2. {
  3. DBUG_ENTER("my_free");
  4. DBUG_PRINT("my",("ptr: %p", ptr));
  5. free(ptr);
  6. DBUG_VOID_RETURN;
  7. }

mysql层的内存分配的更多相关文章

  1. MYSQL,innodb_buffer_pool_size内存分配

    为MYSQL.innodb_buffer_pool_size=8G.MySQL一起动就会将占用掉8G内存(觉得TOP能够看到内存被使用了8G),可是近期才细致研究一下.原来不是这种(可能自己对Linu ...

  2. 深入理解Linux内存分配

    深入理解Linux内存分配 为了写一个用户层程序,你也许会声明一个全局变量,这个全局变量可能是一个int类型也可能是一个数组,而声明之后你有可能会先初始化它,也有可能放在之后用到它的时候再初始化.除此 ...

  3. Android O Bitmap 内存分配

      我们知道,一般认为在Android进程的内存模型中,heap分为两部分,一部分是native heap,一部分是Dalvik heap(实际上也是native heap的一部分).   Andro ...

  4. mysql 与linux ~ 内存分析与调优

    一 简介:linux内存和mysql二 分类   1 用户空间和内核空间      用户空间内存,从低到高分别是五种不同的内存段      1 只读段 包含代码和常量等      2 数据段 包含全局 ...

  5. 高性能go服务之高效内存分配

    高性能go服务之高效内存分配 手动内存管理真的很坑爹(如C C++),好在我们有强大的自动化系统能够管理内存分配和生命周期,从而解放我们的双手. 但是呢,如果你想通过调整JVM垃圾回收器参数或者是优化 ...

  6. TCMalloc优化MySQL、Nginx内存管理

    TCMalloc的全称为Thread-Caching Malloc,是谷歌开发的开源工具google-perftools中的一个成员. 与标准的glibc库的Malloc相比,TCMalloc库在内存 ...

  7. java\c程序的内存分配

    JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该 ...

  8. <转载>内存管理内幕-动态分配的选择、折衷和实现 对malloc内存分配有个简单的描述,对内存管理有个大致的说明

    这篇文章看后感觉不错,和我在glibc下的hurdmalloc.c文件里关于malloc的实现基本意思相同,同时,这篇文章还介绍了一些内存管理方面的知识,值得推荐. 原文链接地址为:http://ww ...

  9. c++内存分配

    [导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不 ...

随机推荐

  1. arm家族小检阅

  2. spring-boot @Async 的使用、自定义Executor的配置方法

    1. TaskExecutor Spring异步线程池的接口类,其实质是java.util.concurrent.Executor Spring 已经实现的异常线程池: 1. SimpleAsyncT ...

  3. 2018.10.12 NOIP模拟 数据结构(线段树)

    传送门 sb线段树题居然还卡常. 修改操作直接更新区间最小值和区间标记下传即可. 询问加起来最多5e65e65e6个数. 因此直接询问5e65e65e6次最小值就行了. 代码

  4. 2018.09.28 hdu5435A serious math problem(数位dp)

    传送门 数位dp卡常题. 写了一发dfs版本的发现过不了233. 于是赶紧转循环版本. 预处理出f数组. f[i][j]f[i][j]f[i][j]表示前i位数异或和为j的方案数. 然后每次直接数位d ...

  5. 2018.09.14 bzoj2982: combination(Lucas定理)

    传送门 貌似就是lucas的板子题啊. 练一练手感觉挺舒服的^_^ 代码: #include<bits/stdc++.h> #define mod 10007 #define ll lon ...

  6. arduino 与 android 通过TCP进行字节收发

    arduino #include <avr/wdt.h> #include <SoftwareSerial.h> #define FPIN 13 SoftwareSerial ...

  7. dj cookie & session组件

    Cookie概述 什么叫Cookie Cookie翻译成中文是小甜点,小饼干的意思.在HTTP中它表示服务器送给客户端浏览器的小甜点.其实Cookie是key-value结构,类似于一个python中 ...

  8. HDU 3177 Crixalis's Equipment (贪心,差值)

    题意:判断 n 件物品是否可以搬进洞里,每件物品有实际体积A和移动时的额外体积 B . 析:第一反应就是贪心,一想是不是按B从大到小,然后一想,不对,比如体积是20,第一个 是A=11, B=19.第 ...

  9. RepositionBars的用法和参数的意义(引用别人的)

    MFC窗口位置管理详细分析及实例 在一般用MFC编写的程序的窗口客户区中,可能有好几个子窗口(具有WM_CHILD风格的窗口).上边是工具栏,中间是视图窗口,下边是状态栏.三个窗 口在框架的客户区里和 ...

  10. Python学习-34.Python中os模块的一些方法(二)

    stat方法: 用于获取文件信息,例如创建时间.文件大小等. import os filestate=os.stat("e:/temp/test.txt") print(files ...