API调用以获取当前的过程大小
API call to get current heap size of process?
我正在调试大型C 应用程序中的缓慢内存泄漏,我想在程序中的各个点上打印出 current heap大小。/p>
除了打开和解析/proc/PID/statm
外,我可以从中获得此信息吗?
但是,一篇帖子建议sbrk()
返回当前的堆指针,而不是我想要的100%。(第二个问题:sbrk()
值的更改是否对应于当前堆大小的变化?)
我看上去很奇怪,没有系统调用...
谢谢
更新i
我已经在调用sbrk()
和读取proc/.../statm
之间进行了一些测试比较。看来sbrk()
没有反映实际分配。相反,statm
似乎测量了实际分配,而sbrk()
显示了总堆大小。
大块的总批量增量(等于页面大小?)。
下面的测试程序会产生此输出( heap size sbrk()
和记忆使用情况,如/proc/.../statm
报道,清楚地显示了差异:
0 ALLOC: HEAP SIZE: 0
MEMORY USAGE: 1308 201 174 2 0 566 0
1 ALLOC: HEAP SIZE: 135168
MEMORY USAGE: 1565 212 184 2 0 823 0
2 ALLOC: HEAP SIZE: 135168
MEMORY USAGE: 1822 216 187 2 0 1080 0
3 ALLOC: HEAP SIZE: 135168
MEMORY USAGE: 2079 217 187 2 0 1337 0
4 ALLOC: HEAP SIZE: 135168
MEMORY USAGE: 2336 218 187 2 0 1594 0
5 ALLOC: HEAP SIZE: 135168
MEMORY USAGE: 2593 219 187 2 0 1851 0
0 FREE: HEAP SIZE: 135168
MEMORY USAGE: 3364 225 189 2 0 2622 0
1 FREE: HEAP SIZE: 135168
MEMORY USAGE: 3107 224 189 2 0 2365 0
2 FREE: HEAP SIZE: 135168
MEMORY USAGE: 2850 223 189 2 0 2108 0
3 FREE: HEAP SIZE: 135168
MEMORY USAGE: 2593 222 189 2 0 1851 0
4 FREE: HEAP SIZE: 135168
MEMORY USAGE: 2336 221 189 2 0 1594 0
5 FREE: HEAP SIZE: 135168
MEMORY USAGE: 2079 220 189 2 0 1337 0
测试程序
class CfgProfileList
{
public:
bool obtainSystemProfileList();
void leakObjTest();
std::set<std::string> mProfileList;
private:
char dummy[1024 * 1024]; // use up some space
};
class ComUtil
{
public:
static void printMemoryUsage();
private:
static unsigned int mHeapOrigin;
};
/* static */
unsigned int ComUtil::mHeapOrigin = 0;
// Print current process memory utilization
/* static */ void
ComUtil::printMemoryUsage()
{
unsigned int pHeap = (unsigned int)sbrk(0);
if (mHeapOrigin == 0)
mHeapOrigin = pHeap;
printf("HEAP SIZE: %un", pHeap - mHeapOrigin);
char fname[256], line[256];
sprintf(fname, "/proc/%d/statm", getpid());
FILE *pFile = fopen(fname, "r");
if (!pFile)
return;
fgets(line, 255, pFile);
fclose(pFile);
printf("MEMORY USAGE: %s", line);
}
void
CfgProfileList::leakObjTest()
{
CfgProfileList *pointerList[50];
int n = 10;
int sleep = 100000;
printf("OBJECT ALLOCATIONn");
for (int i = 0; i < n; i++)
{
pointerList[i] = new CfgProfileList;
printf("%d ALLOC: ", i);
ComUtil::printMemoryUsage();
usleep(sleep);
}
printf("n");
for (int i = 0; i < n; i++)
{
delete pointerList[i];
printf("%d FREE: ", i);
ComUtil::printMemoryUsage();
usleep(sleep);
}
}
int
main(int argc, char **argv)
{
CfgProfileList pl;
pl.leakObjTest();
}
由于GLIBC的new
基于malloc()
,因此可以使用MALLOC信息和调试功能;例如,您可以将malloc_stats()
的调用添加到您的应用程序中。
#include <malloc.h>
…
malloc_stats();
malloc_stats ()功能prints prints prints(在标准错误)统计信息有关内存的统计信息。 malloc (3)和相关功能。…
您可能还可以看一下
-
mallinfo()
,mallinfo ()函数返回结构的副本,其中包含有关 malloc (3)和相关的内存分配的信息 功能。…
- malloc_hook ,
gnu c库让您可以修改 malloc (3), realloc (3)(3), 和 免费(3)通过指定适当的挂钩功能。您可以使用这些钩子来帮助您调试使用动态内存分配的程序 示例。
- 和
mtrace()
。mtrace ()函数安装内存分配函数的钩函数( malloc (3), realloc (3)<b(3)> Memalign (3), 免费(3))。这些挂钩功能记录了有关内存分配和交易的信息。跟踪信息可用于发现 内存泄漏并尝试在程序中释放非分配内存。
我正在调试大型C 应用程序中的缓慢内存泄漏
您应该尝试使用valgrind(用-g
编译所有代码后)。它是跟踪内存泄漏的一个非常好的工具(但它确实以重要因素减慢了您的程序,也许至少X3或X10)。
我想在程序中的各个点打印出当前的堆尺寸。
我不确定堆大小具有很好的定义含义(但请参阅您的问题的其他答案)。操作系统提供并管理流程的虚拟地址空间,并且某些部分通常称为"堆"。您可以使用PROC(5)和解析(从程序内部)/proc/self/stat
,/proc/self/statm
,/proc/self/status
,/proc/self/maps
,这可以很快。还使用PMAP(1),PS(1),顶部(1)命令(全部使用/proc/
)。MMAP(2)&amp;munmap
,mprotect(2)(和旧的SBRK(2))系统调用可以更改您的虚拟地址空间。C new
使用malloc
通常使用mmap
。但是,free
或delete
通常将释放的内存区域标记为未来malloc
-S可重复使用的内存区域,但不要放弃对系统的内存。
ps。如果valgrind
不起作用,我的猜测是您已经破坏了内存,这比内存泄漏更糟糕。考虑尝试一些消毒剂(和其他仪器),也许是地址消毒剂。当然,启用所有警告和调试信息(请使用g++ -Wall -Wextra -g
编译),并花时间改进源代码以获取 no 警告。最近的海湾合作委员会编译器(So GCC 8在2018年8月)给出了更好的警告,并且比较旧的编译器改进了Sanitizr,因此更新您的g++
编译器可能值得。
- 在C++中调用 MS SQL 存储过程
- 在调用过程中删除 std::函数
- C++:如何在对象构造过程中调用初始值设定项列表之外的成员构造函数
- 是否可以使用InProceChannel使用Java客户端在同一过程中调用C 服务器
- 如何使用ABI调用过程在堆栈上正确传递Float参数
- CPP矢量构造函数在擦除过程中调用
- 在构建过程中捕获所有编译器调用和命令行参数
- 多次调用存储过程时C++连接器"Commands out of sync" mySQL
- 如何使用C/C 系统调用来获取Linux过程中一个过程的当前大小
- 在C++中嵌入Python:在Python脚本中导入模块在一个函数调用过程中有效,但在另一个调用过程中无效
- 远程过程调用-客户端提供的服务
- API调用以获取当前的过程大小
- 远程过程调用和MIDL:如何使用[OUT]属性实现功能
- C 中的远程过程调用(RPC):在硬编码端点时,可以多个客户端侦听一台服务器
- 异步过程调用被另一个线程中断
- 选择远程过程调用 c++ 库
- 从{Python|Ruby|..}到C++的远程过程调用
- 对C++对象的并发远程过程调用
- 异步过程调用
- 用MFC中的异步过程调用中断一个accept winsock调用