- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
Linux glibc 分配器似乎表现得很奇怪。希望有人能对此有所启发。这是我的源文件:
第一个.cpp:
#include <unistd.h>
#include <stdlib.h>
#include <list>
#include <vector>
int main() {
std::list<char*> ptrs;
for(size_t i = 0; i < 50000; ++i) {
ptrs.push_back( new char[1024] );
}
for(size_t i = 0; i < 50000; ++i) {
delete[] ptrs.back();
ptrs.pop_back();
}
ptrs.clear();
sleep(100);
return 0;
}
第二个.cpp:
#include <unistd.h>
#include <stdlib.h>
#include <list>
int main() {
char** ptrs = new char*[50000];
for(size_t i = 0; i < 50000; ++i) {
ptrs[i] = new char[1024];
}
for(size_t i = 0; i < 50000; ++i) {
delete[] ptrs[i];
}
delete[] ptrs;
sleep(100);
return 0;
}
我编译了两者:
$ g++ -o first first.cpp$ g++ -o second second.cpp
I run first, and after it's sleeping, I see the resident memory size:
When I compile first.cpp, and run it, I look at memory with ps:
$ ./first&
$ ps aux | grep first
davidw 9393 1.3 0.3 64344 53016 pts/4 S 23:37 0:00 ./first
$ ./second&
$ ps aux | grep second
davidw 9404 1.0 0.0 12068 1024 pts/4 S 23:38 0:00 ./second
注意常驻内存大小。首先,常驻内存大小为53016k。第二个是1024k。首先,由于某种原因,从未将分配释放回内核。
为什么第一个程序不向内核释放内存,而第二个程序却这样做?我知道第一个程序使用链表,并且链表可能会在与我们释放的数据相同的页面上分配一些节点。但是,这些节点应该被释放,因为我们要弹出这些节点,然后清除链表。如果您通过 valgrind 运行这些程序中的任何一个,它都会返回并且不会出现内存泄漏。可能发生的情况是,first.cpp 中的内存出现碎片,而 secondary.cpp 中却没有。但是,如果释放页面上的所有内存,该页面如何不被释放回内核?内存被释放回内核需要什么?如何修改first.cpp(继续将char*放入列表中)以便将内存让给内核。
最佳答案
这种行为是故意的,glibc 使用一个可调阈值来决定是否实际将内存返回给系统或是否缓存它以供以后重用。在您的第一个程序中,您对每个 push_back
进行了大量的小分配,这些小分配不是连续的 block ,并且可能低于阈值,因此不会返回到操作系统。
调用malloc_trim(0)
清除列表后应该会导致 glibc 立即将空闲内存的最顶层区域返回给系统(下次内存需要sbrk
系统调用是需要的。)
如果您确实需要覆盖默认行为(我不建议这样做,除非分析表明它确实有帮助),那么您可能应该使用 strace 和/或尝试 mallinfo
到查看程序中实际发生的情况,也许可以使用 mallopt
到调整向系统返回内存的阈值。
关于c++ - Linux 分配器不会释放小块内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28874215/
我制作了一个简单的 NodeJS TCP 服务器,Java 客户端发送图像: encodedImage = out.write("IMG;" + encodedImage); out.flush()
我最近(比如 2 天)开始使用带有 XML 的 XSLT 文档。我了解基础知识,并且能够使用引用单独 .XSLT 文档的 .XML 文档生成格式化文档。 我的问题与主题一样,是“是否可以创建一个包含
我是一名优秀的程序员,十分优秀!