我有一个用C++实现的树。
当我运行创建树的代码并使用malloc()插入大约5,000,000 int键时,当我使用Visual 2013运行时,它将使用类似于200 as的(如任务管理器所示)。
当我在每个节点上使用free()释放树时,它将返回到0.5MB的周围。到现在为止一切都还好。
现在,当我使用cygwin编译和运行Visual时,树的大小就像80 in (这是可以的,因为visual Studio添加了调试信息和其他东西),,但是当我释放树时,它的大小没有任何变化!
简单地说:在Visual中运行释放树时,将程序的大小返回到原始大小0.5MB,但是当我在Visual之外编译和运行相同的代码(使用cygwin)时,释放树不会从程序大小(仍然是80 of )中改变任何东西。
那为什么会发生这种事?
更新
释放树后,我尝试再次在树中插入相同的5,000,000 int键。在cygwin的情况下,它没有使用额外的内存,即相同的80 to,这意味着,正如反馈所指出的(谢谢各位+1),内存被释放了,但没有返回到操作系统。
现在的问题是:--如果我有大量内存分配,当释放的时候,我不喜欢把这个空闲的区域保留在程序中。那么,我如何让强制 cygwin将其返回到操作系统呢?
发布于 2017-10-01 12:54:04
不同的恶意行为是不同的。Microsoft可以使用原始堆分配和释放项。
看起来MS在直接原始堆(HeapAlloc/HeapFree)上使用内存。
但是cygwin使用的是本地托管内存系统。
这意味着通过HeapAlloc / HeapFree释放内存将返回给操作系统,并释放相关资源。
在cygwin上自由调用,将返回要重用的内存,但不会将其返回给操作系统。
管理大量内存
如果您有大量需要处理的内存,那么您最好直接管理它们,方法是迭代操作系统,并调用它的基本函数。例如,在Windows上,您可以调用HeapCreate来创建一个单独的堆,并使用HeapAlloc在该单独的大型块分配中分配,用HeapFree释放它们。
当您完成该块时,可以使用HeapDestroy释放所有内存。
发布于 2017-10-01 13:07:41
由于需要与其他进程交互(例如,与向实际管理硬件资源的特权设备驱动程序发出请求相关联的上下文切换),动态请求内存和释放内存可能是代价高昂的操作。
为了减少这种性能命中,malloc() (和calloc()等)和free()可以在内部管理分配的内存池,以避免每次请求或释放内存时访问操作系统的开销。例如,如果调用free(),它可能只是更改内部数据结构,以记录程序不再使用的内存块,但实际上并没有通知操作系统内存已被释放。
malloc()也可能故意过度分配。例如,它可能一次从主机系统请求数to,即使程序的请求要少得多,然后对多个malloc()调用进行阻塞,而不是为malloc()的每个调用向操作系统发出请求。
使用malloc()和free()这样的工作方式,就操作系统而言,程序对free()调用的内存使用量可能不会减少(至少在free()代码根据自己的标准决定将内存返回给主机系统之前是这样的)。对于malloc()的多个调用,可能还会受到内存使用急剧增加的影响,然后会趋于平稳,即使程序多次调用malloc()而不调用free()。
发布于 2017-10-01 15:05:27
通用内存分配程序使用各种启发式方法来尝试和优化常见的分配/去分配模式,但它们必须正确处理所有情况。
在您的特定情况下,如果您的问题具有以下属性,您可能有资格使用一种简单得多的方法:
您可以使用自定义分配器来分配节点,并在批处理中释放节点。下面是一个示例:
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *left, right;
} Node;
typedef struct NodeBlock {
struct NodeBlock *next;
size_t count, size;
Node a[32768];
} NodeBlock;
Node *alloc_node(NodeBlock **node_heapp) {
NodeBlock *ptr = *node_heap;
if (!ptr || ptr->count == ptr->size) {
ptr = calloc(sizeof(*ptr, 1);
if (ptr == NULL)
return NULL;
ptr->size = sizeof(ptr->a) / sizeof(ptr->a[0]);
ptr->next = *node_heap;
*node_heap = ptr;
}
return &ptr->a[ptr->count++];
}
void free_nodes(NodeBlock **node_heapp) {
while (*node_heapp) {
NodeBlock *ptr = *node_heap;
*node_heap = ptr->next;
free(ptr);
}
}上面的代码将节点分批分配:
malloc()很可能对大型请求使用mmap(),在取消分配时将内存交给系统。如果没有观察到这一点,请尝试增加阻塞因子( Node数组a的长度)。https://stackoverflow.com/questions/46512510
复制相似问题