当编程这样典型脑力累之本行,如「超体」附身的世界头号程序员简直叫视作大神来崇拜。在
100offer
之程序员拍卖库中,拥有多年做事更的显赫程序员毫无疑问占据了主力位置,但更加多之非科班出身、有激情与想法的常青程序员也当源源不断地涌现。其实,从菜鸟到大神的逾越说难吗不为难,看看是脑洞大开的卡通,或许你吗可以当三年里成长也「顶级
Coder」。

可自己实在好又写了 malloc 的庞然大物,比较好好用,源文件也杀短.

怎样在三年里成长为顶级 Coder?

 

如果你觉得这是个来噱头的伪命题,笑笑就放弃了,那就真是too young, too
simple, sometimes naive.


100offer 相信,用三年工夫成长也一流Coder是出或的。

当应用程序中替换Linux中Glibc的malloc的季种艺术
http://blog.csdn.net/littlefang/article/details/6052563

您需要之是「自律」和「坚持」。

 

告小心,我们说之凡「Coder」,而未是「Programmer」或「Software
Engineer」。

        
打算优化系统的内存分配,接管glibc提供的内存管理,但是所有工程的代码量很怪,使用malloc、realloc、calloc和free的地方所在都是,如果协调写好之接口需要重命名所有的调用,先不说工作量,部分从没权限查看代码的.a文件就来不自然了。所以要替换掉系统的malloc,保证原有调用的称号不变换。经过尝试,共有四栽方法可轮换,各起优缺点吧。

于Coder,我们是出合理性评价标准的,那便是出席「编程比赛」。

方案1 应用环境变量LD_PRELOAD

除外境内的各种程序设计大赛,100offer
复推荐与海外的编程比赛网站,如「topcoder」、「codeforeces」。这些网站上每个月还发比,只要您产生同贵能上网的计算机便足以免费与,和天底下的Coder竞争,赢得了较量还有美金拿哦!

        
环境变量LD_PRELOAD指定程序运行时事先加载的动态连接库,这个动态链接库中之号子优先级是高的。标准C的各种函数都是存于libc.so.6的文件被,在程序运行时自动链接。使用LD_PRELOAD后,自己编排的malloc的加载顺序高于glibc中的malloc,这样即使实现了交替。用法:

Tips:

         [littlefang]$ LD_PRELOAD=” ./mymalloc.so”

  • 上topCoder的练习室,每天花4-6个钟头练编程。
  • 制定一个计划,比如:每天解决10只初级问题,每周搞定3独中等问题、1个高级问题。
  • 如当某某问题上困住了,马上去论坛求助。要了解,问问题体现了您的合计逻辑,问有好题材吧是用练习的。试着每周在问答网站
    stack over flow 上问一个问题吧!
  • 莫使闭门造车,把您的代码展示被别人看,他们提出的意会于您事半功倍,推荐免费网站coder
    review。
  • 学会看别人的代码,看代码其实正如自己写代码更难,但是高手是足以随心所欲调用别人的代码的,推荐gitub,可以轻松地找到海量的开源代码。
  • 建议采取部分外部的艺术克服拖延症,比如开通一个博客、或微博,每天以点记下而今天举行过的同样件重要之事务,保证每天晚上都带在英雄的满足感入睡。

        
这是极端实用的替换方法,动态链接库加载过程被提供了初始化函数,可以随便之获系统malloc的句柄,再将它举行更的田间管理,Hoard(参见深入Linux的内存管理,关于PTMalloc3、Hoard和TCMalloc)的就算是这样实现的。

设若坚持就以上这些,你一点一滴可改为同称世界级Coder。

方案2  malloc调试变量

用留意的凡,编程比赛关注的凡算法能力;要改成平等称呼「 Programmer」或「
Software Engineer」,你还需要种阅。

        
__malloc_hook是一模一样组glibc提供的malloc调试变量中之一个,这组变量包括:

正而Facebook喜欢雇佣所谓的 「Full Stack
Programmer」,就是一个总人口于计划性、到互相、html、css、javascript、server、sql、架构,以及数额统计还能举行。成为Full
Stack Programmer最好之点子就是是无休止做个人项目。

 

在座Hackathons 或 game jams 就是锻炼型能力的好方法。

[cpp:nogutter] view
plaincopyprint?

每当规定的岁月内,一浩大开发者分享、讨论、组队、分工协作,用创意思考完成项目任务。无论是制作一个娱乐,还是网站,在方方面面项目的长河被,你会持续经历发现问题、解决问题、获得经验的进程,从而确保在事实上工作面临吗能够轻松解决问题。

  1. void *(*__malloc_hook)(size_t size, const void *caller);   
  2.   
  3. void *(*__realloc_hook)(void *ptr, size_t size, const void *caller);   
  4.   
  5. void *(*__memalign_hook)(size_t alignment, size_t size, const void *caller);   
  6.   
  7. void (*__free_hook)(void *ptr, const void *caller);   
  8.   
  9. void (*__malloc_initialize_hook)(void);   
  10.   
  11. void (*__after_morecore_hook)(void);  

100offer 小结

 

出道时间并无是衡量人才能力的绝标准,碌碌无为的「老人」在各个行业还无稀罕。在3年以内能否成才也平称作美的
Coder 或 Programmer,其实在于你对所召开业务的喻程度。

一经您以先后中形容及”__malloc_hook =
my_malloc_hook;”,之后的malloc调用都见面采用my_malloc_hook函数,方便易行。但是这组调试变量不是线程安全的,当您想就此系统malloc的下只得把他们转移回去,多线程调用就得达锁了。因此方案2无怪适用于系统内存优化,勉强用来简单管理线程内存以。

对所开政工知道的愈益充分,你就算见面做的一发好。

         详细用法请猛击这里

变成平等曰好的程序员和成为另外行当之高手一样,都急需不歇地念、练习、反省同总。这不但是早期3年的渴求,而是贯穿整个职业生涯的要。

方案3 编译自己之libmalloc.a

以100offer
底拍卖库中,拥有不饱于现状的上进心的程序员往往会得重新多HR的推崇,收到再多的面试邀请。

        
关于重载glibc的malloc库,ChinaUnix上产生诸如此类的座谈:

今天,100offer
11月程序员拍卖第一想正好于酷暑开展着,24日将上马11月第二可望拍卖,申请渠道已经开通。希望
100offer
可知助力你的工作发展的路,助你以最为可、最有前景的职务上落实一个程序员的优异。

而本身之所以cc -o myprog myprog.c -lmylib,
而无思改缺省之ld的下令执行参数或者linker脚本,不知可可以?

100offer 程序员拍卖

这个法子确实比较优良,只需要make一不行就OK了,不用转环境变量,省得担心后台运行的题目。后面有人过来给楼主试试,不知底楼主试了没,我尝试了转。

假如一旦拿系统内存管理起,首先还是如果为操作系统申请内存,这个题目对LD_PRELOAD方案充分简单,链接库加载时就好拿glibc中的malloc加载进来,以后直接调用就可以了,如:

real_malloc = dlsym(RTLD_NEXT, “malloc”);

不过若而使用好编译的malloc库,在您调用dlsym这个函数时,dlsym会调用dlerror,dlerror会调用calloc,calloc要调用malloc,而你的malloc正在初始化等待dlsym返回中,于是死循环了。有人说,在调用没有初始化完毕的malloc时,返回NULL,我试了dlsym不服气账,加载可耻的黄了。在满世界的搜寻dlsym的替代品未果后,我拿目光瞄住了tcmalloc(参见深入Linux的内存管理,关于PTMalloc3、Hoard和TCMalloc)。Tcmalloc使用时索要在链接时增长-ltcmalloc即可,它代码里呢尚无动用dlsym,大略了羁押了产它们的代码,它采取mmap从网获得的内存。

void *mmap(void *addr, size_t len, int prot, int flags, int fildes,
off_t off);

这种方法从页面级就设对准系内存进行田间管理,Glibc中的malloc就是采取mmap和brk两只函数从程序堆着收获内存的。无疑,这较用malloc分配的内存复杂了累累。

方案4 链接过程控制

ld中发出一个选择
–wrap,当找某个符号时,它先先分析__wrap_symbol, 解析不顶才去解析symbol。例如:

 

[cpp:nogutter] view
plaincopyprint?

  1. void *__wrap_malloc (size_t c)  
  2.   
  3. {  
  4.   
  5.      printf (“malloc called with %zu/n”, c);  
  6.   
  7.      return __real_malloc (c);  
  8.   
  9. }  

 

当其他文件及君兑现__wrap_malloc函数的文件链接时以–wrap malloc
,则怀有到malloc的调用都是会链接到__wrap_malloc上。只有调用__reall_malloc时才会调用真正的malloc。

 

[cpp:nogutter] view
plaincopyprint?

  1. #include <stdio.h>  
  2.   
  3. #include <stdlib.h>  
  4.   
  5.    
  6.   
  7. void *__real_malloc(size_t);  
  8.   
  9.    
  10.   
  11. void *__wrap_malloc(size_t c)  
  12.   
  13. {  
  14.   
  15.         printf(“My MALLOC called: %d/n”, c);  
  16.   
  17.         return __real_malloc(c);  
  18.   
  19. }  
  20.   
  21.    
  22.   
  23. int main (int argc, char *argv[])  
  24.   
  25. {  
  26.   
  27.         void *ptr = malloc(12);  
  28.   
  29.    
  30.   
  31.         return 0;  
  32.   
  33. }  

 

编译 

[littlefang]$ gcc wrap.c -o wrap -Wl,-wrap,malloc

运行 

[littlefang]$ ./wrap

My MALLOC called: 12

Gcc或g++编译使用
–Wl选项,以指定链接器参数,比如以替换malloc,free,realloc就使因此

gcc wrap.c -o wrap -Wl,-wrap,malloc  -Wl,-wrap,free  -Wl,-wrap,realloc。

特意需要留意的是,如果您的__wrap_malloc是为此C++实现之,千万不要遗忘加上extern
“C”做修饰,不然会产出”undefine reference to __wrap_malloc”。

 

 

 

分享到:

  • 上一篇:深入Linux的内存管理,关于PTMalloc3、Hoard和TCMalloc
  • 下一篇:volatile关键字与原子操作的区分

http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/  “应用
Valgrind 发现 Linux 程序的内存问题 “

 

以下为转载,原文不知.


并非重载全局 ::operator new()
日期:2011年3月14日 | 来源:看文章 | 编辑9号小组 | 看文章

  总之,第二栽重载方式接近功能又增长,但事实上与程序里应用的另 C++
library 很为难无缝配合。

  综上,对于现实生活中之 C++ 项目,重载 ::operator new()
几乎没用武之地,因为老麻烦处理好与程序所用底 C++ library
的关系,毕竟大多数 library 在计划之时光没设想到您晤面重载 ::operator
new() 并强塞给她。

  如果实在需要定制内存分配,该如何办?

  替代方式

  很简单,替换 malloc。如果欲,直接由 malloc 层面入手,通过
LD_PRELOAD 来加载一个 .so,其中有 malloc/free 的替代实现(drop-in
replacement),这样会而为 C 和 C++ 代码服务,而且免 C++ 重载
::operator new() 的阴角落。

  对于“检测内存错误”这同样就此法,我们得以用 valgrind 或者 dmalloc 或者
efence
来达到同等之目的,专业的除错工具比自己山寨一个内存检查器要借助谱。

  对于“统计内存以数据”,替换 malloc
同样会赢得足够的信息,因为咱们可就此 backtrace() 函数来取得调用栈,这比
new (__FILE__, __LINE__) 的音还增长。比方说而通过分析
(__FILE__, __LINE__) 发现 std::string
大量分配释放内存,有超出预想的出,但是若倒是无懂得代码里呐部分以多次创建和销毁
std::string 对象,因为 (__FILE__, __LINE__)
只能告诉您太内层的调用函数。用 backtrace() 能找到真正的倡导调用者。

  对于“性能优化”这无异用法,我觉得这即底多线程开发中,自己实现一个能打败系统默认的
malloc
的外存分配器是休具体的。一个通用的内存分配器本来就生出一定之难度,为多线程程序实现一个平安以及高效之通用(全局)内存分配器超出了相似开发人员的能力。不如使用现有的对多核多线程优化的
malloc,例如 Google tcmalloc 和 Intel TBB 2.2 里的内存分配器。好于这些
allocator 都非是侵入式的,也毫无重载 ::operator new()。

  也单独的 class 重载 operator new() 有题目呢?

  和大局 ::operator new() 不同,per-class operator new() 和 operator
delete () 的震慑对如稍得几近,它才影响本 class 及其派生类。似乎重载 member
operator new() 是行得通之。我本着之持反对态度。

  如果一个 class Node 需要重载 member operator
new(),说明它用了奇之内存分配政策,常见的状是使了内存池或对象池。我宁可把及时等同真相明显地张出来,而休是反
new Node 的默认行为。具体地说,是用 factory 来创建对象,比如 static
Node* Node::createNode() 或者 static shared_ptr<Node>
Node::createNode();。

  这足以归纳为极其小惊讶原则:如果自身于代码里读到 Node* p = new
Node,我会觉得它于 heap 上分红了内存,如果 Node class 重载了 member
operator new(),那么自己如果优先仔细翻阅 node.h
才会觉察实际就行代码使用了个人的外存池。为什么不写得明白一点为?写成
Node* p = Node::createNode(),那么自己能猜到 Node::createNode()
肯定开了什么和 new Node 不等同的事情,免得将来震惊。

  The Zen of Python 说 explicit is better than
implicit,我深信。

  总结:重载 ::operator new()
或许在好几临时之场合能答应只急,但是未应当作为同栽政策来以。如果欲,我们得打
malloc 层面入手,彻底而完善地更迭内存分配器。

  参考文献:

  [1] 侯捷,《池內春秋—— Memory Pool
的設計哲學與無痛運用》,《程序员》2002 年第 9 期。