Ker*_* SB 56 c c++ memory-management
就各自的语言标准而言,C仅通过malloc()族提供动态内存分配,而在C++中,最常见的分配形式是由::operator new().C风格的malloc也有C++版本,许多"baby的第一个分配器"示例使用它作为其核心分配函数,但我很好奇当代编译器如何实现实际的生产操作符 - new.
它只是一个薄的包装器malloc(),或者由于与典型的C程序相比,典型的C++程序的内存分配行为有很大不同,它是否会根本不同地实现?
[ 编辑:我认为主要区别通常描述如下:AC程序具有更少,更大,更长寿的分配,而C++程序具有许多小的短期分配.如果错误的话,请随意加入,但听起来有人会考虑到这一点.
对于像GCC这样的编译器,只需要一个单独的核心分配实现并将其用于所有相关语言就很容易,因此我想知道在每种语言中尝试优化分配性能的细节是否存在差异.
更新:感谢所有的好答案!看起来在GCC中这完全由ptmalloc解决,而且MSVC也在malloc核心使用.有谁知道MSVC-malloc是如何实现的?
NPE*_*NPE 48
以下是使用的实现g++ 4.6.1:
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) throw (std::bad_alloc)
{
void *p;
/* malloc (0) is unpredictable; avoid it. */
if (sz == 0)
sz = 1;
p = (void *) malloc (sz);
while (p == 0)
{
new_handler handler = __new_handler;
if (! handler)
#ifdef __EXCEPTIONS
throw bad_alloc();
#else
std::abort();
#endif
handler ();
p = (void *) malloc (sz);
}
return p;
}
Run Code Online (Sandbox Code Playgroud)
这可以在libstdc++-v3/libsupc++/new_op.ccg ++源代码发行版中找到.
正如你所看到的,它是一个相当薄的包装器malloc.
编辑在许多系统上malloc,通常可以通过调用mallopt或设置环境变量来微调其行为.这是一篇讨论Linux上可用功能的文章.
根据维基百科,glibc版本2.3+使用被称为分配器的修改版本ptmalloc,它本身是dlmalloc由Doug Lea设计的衍生物.有趣的是,在一篇关于dlmalloc Doug Lea 的文章中给出了以下观点(强调我的观点):
在编写了一些几乎完全依赖于分配动态内存的C++程序之后,我编写了第一个分配器版本.我发现它们的运行速度要慢得多,而且内存消耗总量比我预期的要多得多.这是由于我运行的系统上的内存分配器的特性(主要是当时版本的SunOs和BSD).为了解决这个问题,我首先在C++中编写了许多专用分配器,通常是通过为各种类重载operator new.其中一些在关于C++分配技术的论文中有所描述,该论文已被改编成1989 C++ Report文章的容器类的一些存储分配技术.
但是,我很快就意识到,在构建当时正在编写的各种通用编程支持类时,为每个新类构建一个特殊的分配器,这些类往往是动态分配和大量使用的,这不是一个好的策略.(从1986年到1991年,我是libg ++的主要作者,GNU C++库.)需要一个更广泛的解决方案 - 在正常的C++和C加载下编写一个足够好的分配器,这样程序员就不会想要编写专用分配器,除非在非常特殊的条件下.
本文介绍了此分配器的一些主要设计目标,算法和实现注意事项.
cyc*_*130 12
glibc new operator是malloc的一个薄包装器.glibc malloc对不同的大小分配请求使用不同的策略.您可以在此处查看实施或至少注释.
以下是malloc.c中注释的摘录:
/*
47 This is not the fastest, most space-conserving, most portable, or
48 most tunable malloc ever written. However it is among the fastest
49 while also being among the most space-conserving, portable and tunable.
50 Consistent balance across these factors results in a good general-purpose
51 allocator for malloc-intensive programs.
52
53 The main properties of the algorithms are:
54 * For large (>= 512 bytes) requests, it is a pure best-fit allocator,
55 with ties normally decided via FIFO (i.e. least recently used).
56 * For small (<= 64 bytes by default) requests, it is a caching
57 allocator, that maintains pools of quickly recycled chunks.
58 * In between, and for combinations of large and small requests, it does
59 the best it can trying to meet both goals at once.
60 * For very large requests (>= 128KB by default), it relies on system
61 memory mapping facilities, if supported.
*/
Run Code Online (Sandbox Code Playgroud)
In *_*ico 10
在Visual C++中,单步执行new表达式会引导我进入以下代码段new.cpp:
#include <cstdlib>
#include <new>
_C_LIB_DECL
int __cdecl _callnewh(size_t size) _THROW1(_STD bad_alloc);
_END_C_LIB_DECL
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{ // try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{ // report no memory
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
Run Code Online (Sandbox Code Playgroud)
所以VC++ new也包含了这个malloc()电话.
| 归档时间: |
|
| 查看次数: |
3815 次 |
| 最近记录: |