印度域名注册网站,如何解决网站图片打开慢,自己做的网站怎么显示表格边框,网站后台忘记账号密码Tcmalloc
Ptmalloc在性能上还是存在一些问题的#xff0c;比如不同分配区#xff08;arena#xff09;的内存不能交替使用#xff0c;比如每个内存块分配都要浪费8字节内存等等#xff0c;所以一般倾向于使用第三方的malloc。
Tcmalloc是Google gperftools里的组件之一。…Tcmalloc
Ptmalloc在性能上还是存在一些问题的比如不同分配区arena的内存不能交替使用比如每个内存块分配都要浪费8字节内存等等所以一般倾向于使用第三方的malloc。
Tcmalloc是Google gperftools里的组件之一。全名是 thread cache malloc线程缓存分配器其内存管理分为线程内存和中央堆两部分。 小内存分配
对于小块内存分配其内部维护了60个不同大小的分配器实际源码中看到的是86个和ptmalloc不同的是它的每个分配器的大小差是不同的依此按8字节、16字节、32字节等间隔开。在内存分配的时候会找到最小复合条件的比如833字节到1024字节的内存分配请求都会分配一个1024大小的内存块。如果这些分配器的剩余内存不够了会向中央堆申请一些内存打碎以后填入对应分配器中。同样如果中央堆也没内存了就向中央内存分配器申请内存。 在线程缓存内的60个分配器_文档上说60个但是我在2.0的代码里看到得是86个_分别维护了一个大小固定的自由空间链表直接由这些链表分配内存的时候是不加锁的。但是中央堆是所有线程共享的在由其分配内存的时候会加自旋锁(spin lock)。
在线程内存池每次从中央堆申请内存的时候分配多少内存也直接影响分配性能。申请地太少会导致频繁访问中央堆也就会频繁加锁而申请地太多会导致内存浪费。在tcmalloc里这个每次申请的内存量是动态调整的调整方式使用了类似把tcp窗口反过来用的慢启动slow start算法调整max_length 每次申请内存是申请max_length和每个分配器对应的num_objects_to_move中取小的值的个数的内存块。
num_objects_to_move取值比较简单是以64K为基准并且最小不低于2最大不高于32的值。也就是说对于大于等于32K的分配器这个值为2好像没有这样的分配器 class对于小于2K的分配器统一为32。其他的会把数据调整到64K / size 的个数。可能是经验数值目前2.0版本里的代码是这么写的
对于max_length就比较复杂了而且其更多是用于释放内存。max_length由1开始在其小于num_objects_to_move的时候每次累加1大于等于的时候累加num_objects_to_move。释放内存的时候首先max_length会对齐到num_objects_to_move然后在大于num_objects_to_move的释放次数超过一定阀值则会按num_objects_to_move缩减大小。
大内存分配
对于大内存分配(大于8个分页, 即32K)tcmalloc直接在中央堆里分配。中央堆的内存管理是以分页为单位的同样按大小维护了256个空闲空间链表前255个分别是1个分页、2个分页到255个分页的空闲空间最后一个是更多分页的小的空间。这里的空间如果不够用就会直接从系统申请了。 分页管理 – span
Tcmalloc使用一种叫span的东东来管理内存分页一个span可以包含几个连续分页。一个span的状态只有未分配(这时候在空闲链表中)作为大对象分配或作为小对象分配这时候span内记录了小对象的class size。
在32位系统中span分为两级由中央分配器管理。第一级有2^5个节点第二级是2^15个。32位总共只能有2^20个分页每个分页4KB 2^12。(骗纸我在代码里明明看到的是2^7和2^13定义了TCMALLOC_LARGE_PAGES宏之后才是 2^5和2^15可是所有的代码或者编辑脚本里都没定义这个宏可能是文档没更新)
在64为系统中有三级。
在资源释放的时候首先计算其分页编号然后再查找出它对应的span如果它是一个小对象则直接归入小对象分配器的空闲链表。等到空闲空间足够大以后划入中央堆。如果是大对象则会把物理地址连续的前后的span也找出来如果空闲则合并并归入中央堆中。
而线程缓存内的分配器会根据max_length、num_objects_to_move和上一次垃圾收集到现在为止的最小链表长度按一定的策略回收资源到中央堆中具体的算法不再复述tcmalloc的文档写得比较清楚。同样可以在需要时减少某一个线程的max_length来转移内存但是要等到那个线程下一次执行free触发垃圾回收之后才会真正把内存返还中央堆。
简而言之就是
**小内存 线程缓存队列 - 中央堆 - 中央页分配器从系统分配
大内存 中央堆 - 向系统请求
Tcmalloc的管理策略和ptmalloc有很大区别理论上性能提高的主要原因在线程缓存不加锁和少量操作的自旋锁上。不过按照它的实现方式不适合多线程频繁分配大于8个分页32KB的内存。否则自旋锁争用会相当厉害不过这种情况也比较少。而减少和中央堆交互又依赖于他的线程缓存长度自适应算法。
还有就是它使用了外部的数据结构来管理span list这样不会每次分配内存都要浪费header的长度。但是他的对齐操作又比ptmalloc多浪费了一些内存。有点空间换时间的意思
所以无论是ptmalloc还是tcmalloc都应该尽量减少大内存的分配和释放。尽量先分配、后释放。 ptmalloc与tcmalloc的不足 都是针对小内存分配和管理对大块内存还是直接用了系统调用。应该尽量避免大内存的malloc/new、free/delete操作。频繁分配小内存例如对bool、int、short进行new的时候造成内存浪费。