码迷,mamicode.com
首页 > 其他好文 > 详细

Blender内存管理库(bf_intern_guardedalloc)

时间:2020-10-06 20:50:13      阅读:32      评论:0      收藏:0      [点我收藏+]

标签:tail   实现   form   else   lock   内存分配   启动参数   相关   mes   

Blender内部定义了自己内存泄漏检测机制,同时提供了了二套实现机制,函数整合于于bf_intern_guardedalloc库中:

mallocn_lockfree_impl.c和mallocn_guarded_impl.c分别实现了这二套内存分配机制,头文件定义于MEM_guardedalloc.h中,为方便实现二种机制的切换,函数头使用的是函数指针方式,以便于动态切换。

mallocn_lockfree_impl.c中的实现用于正常工作模式,mallocn_guarded_impl.c的实现用于调试模式,提供更多信息,更方便定位内存问题。

mallocn.c中实现函数指针被赋值,默认使用mallocn_lockfree_impl.c中的函数,如果需要使用mallocn_guarded_impl.c中的函数,只需要调用MEM_use_guarded_allocator函数,实现二套机制的切换。

在blender主程序文件中createor.c中,只有当明确指明调试模式时使用guarded模式内存分配,以方便理准确定位内存问题

 1 /* NOTE: Special exception for guarded allocator type switch:
 2    *       we need to perform switch from lock-free to fully
 3    *       guarded allocator before any allocation happened.
 4    */
 5   {
 6     int i;
 7     for (i = 0; i < argc; i++) {
 8       if (STR_ELEM(argv[i], "-d", "--debug", "--debug-memory", "--debug-all")) {
 9         printf("Switching to fully guarded memory allocator.\n");
10         MEM_use_guarded_allocator();
11         break;
12       }
13       else if (STREQ(argv[i], "--")) {
14         break;
15       }
16     }
17     MEM_initialize_memleak_detection();
18   }

 同时在第17行调用MEM_initialize_memleak_detection()函数实例化MemLeakPrinter(leak_detector.cc中定义)类到静态变量中,用于初始内存泄漏检测。该类只定义了析构函数,因此在程序结束时自动释放时调用析构函数,实现打印内存泄漏信息。也就无需主动调用,正发布版程序中也无需处理,不用担心性能。

 

例如:MEM_guardedalloc.h中定义的函数指针:extern void *(*MEM_callocN)(size_t len, const char *str) ,在mallocn.c中将它赋值

void *(*MEM_callocN)(size_t len, const char *str) = MEM_guarded_callocN;

MME_lockfree_callocN函数定义于mallocn_guarded_impl.c文件中,如下: 

 

 1 void *MEM_guarded_mallocN(size_t len, const char *str)
 2 {
 3   MemHead *memh;
 4 
 5   len = SIZET_ALIGN_4(len);
 6 
 7   memh = (MemHead *)malloc(len + sizeof(MemHead) + sizeof(MemTail));
 8 
 9   if (LIKELY(memh)) {
10     make_memhead_header(memh, len, str);
11     if (UNLIKELY(malloc_debug_memset && len)) {
12       memset(memh + 1, 255, len);
13     }
14 
15 #ifdef DEBUG_MEMCOUNTER
16     if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
17       memcount_raise(__func__);
18     memh->_count = _mallocn_count++;
19 #endif
20     return (++memh);
21   }
22   print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
23               SIZET_ARG(len),
24               str,
25               (unsigned int)mem_in_use);
26   return NULL;
27 }

 

 

 

通过代码分析可知,内存分配的保护措施就是,在请求分配内存块时,在前面额外增加了一个MemHead和MemTail,它存储了请求的内存块大小,同时更新totblock,mem_in_use,peak_mem三个与内存保护相关变量

以下是Mem_freeN指向的函数MEM_gurded_freeN(它与Mem_allocN相对应,用于释放内存)


 1 void MEM_guarded_freeN(void *vmemh)
 2 {
 3   MemTail *memt;
 4   MemHead *memh = vmemh;
 5   const char *name;
 6 
 7   if (memh == NULL) {
 8     MemorY_ErroR("free", "attempt to free NULL pointer");
 9     /* print_error(err_stream, "%d\n", (memh+4000)->tag1); */
10     return;
11   }
12 
13   if (sizeof(intptr_t) == 8) {
14     if (((intptr_t)memh) & 0x7) {
15       MemorY_ErroR("free", "attempt to free illegal pointer");
16       return;
17     }
18   }
19   else {
20     if (((intptr_t)memh) & 0x3) {
21       MemorY_ErroR("free", "attempt to free illegal pointer");
22       return;
23     }
24   }
25 
26   memh--;
27   if (memh->tag1 == MEMFREE && memh->tag2 == MEMFREE) {
28     MemorY_ErroR(memh->name, "double free");
29     return;
30   }
31 
32   if ((memh->tag1 == MEMTAG1) && (memh->tag2 == MEMTAG2) && ((memh->len & 0x3) == 0)) {
33     memt = (MemTail *)(((char *)memh) + sizeof(MemHead) + memh->len);
34     if (memt->tag3 == MEMTAG3) {
35 
36       if (leak_detector_has_run) {
37         MemorY_ErroR(memh->name, free_after_leak_detection_message);
38       }
39 
40       memh->tag1 = MEMFREE;
41       memh->tag2 = MEMFREE;
42       memt->tag3 = MEMFREE;
43       /* after tags !!! */
44       rem_memblock(memh);
45 
46       return;
47     }
48     MemorY_ErroR(memh->name, "end corrupt");
49     name = check_memlist(memh);
50     if (name != NULL) {
51       if (name != memh->name) {
52         MemorY_ErroR(name, "is also corrupt");
53       }
54     }
55   }
56   else {
57     mem_lock_thread();
58     name = check_memlist(memh);
59     mem_unlock_thread();
60     if (name == NULL) {
61       MemorY_ErroR("free", "pointer not in memlist");
62     }
63     else {
64       MemorY_ErroR(name, "error in header");
65     }
66   }
67 
68   totblock--;
69   /* here a DUMP should happen */
70 }

 

只要通过该库中函数分配的内存就能通过设置启动参数,在程序结束时显示内存泄漏等相关情况。

 

Blender内存管理库(bf_intern_guardedalloc)

标签:tail   实现   form   else   lock   内存分配   启动参数   相关   mes   

原文地址:https://www.cnblogs.com/jiaping/p/8093304.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!