use*_*181 4 c malloc memory-leaks suse
我在 Suse Linux Enterprise 上运行我的 C 程序,它压缩了几千个大文件(大小在 10MB 到 100MB 之间),随着程序的运行,程序变得越来越慢(它在英特尔 Sandy Bridge 板上运行 32 个线程的多线程)。当程序完成并再次运行时,它仍然很慢。
当我观察程序运行时,我看到程序运行时内存正在耗尽,你会认为这只是一个典型的内存泄漏问题。但是,由于正常的 malloc()/free() 不匹配,我希望所有内存在程序终止时返回。但是,当程序完成时,大部分内存不会被回收。free 或 top 命令显示 Mem:总共 63996M,已使用 63724M,当程序减速停止时有 272M 空闲,但在终止后,空闲内存仅增长回约 3660M。当程序重新运行时,空闲内存很快就用完了。
顶部程序仅显示该程序在运行时最多使用了 4% 左右的内存。
我认为这可能是内存碎片问题,但是,我构建了一个小型测试程序来模拟程序中的所有内存分配活动(内置了许多随机方面 - 大小/数量),并且它始终返回所有内存完成。所以,我不认为是这样。
问题:
是否可能存在会永久丢失内存的 malloc()/free() 不匹配,即即使在进程完成之后?
C 程序(不是 C++)中还有哪些其他东西会导致永久性内存丢失,即在程序完成后,甚至终端窗口关闭?只有重新启动才能恢复内存。我已经阅读了其他关于文件未关闭导致问题的帖子,但是,我认为我没有这个问题。
查看 top 和 free 的内存统计数据是否有效,即它们是否准确地描述了内存情况?它们似乎确实与程序的缓慢相对应。
如果程序只显示4%的内存使用率,valgrind之类的会发现这个问题吗?
是否可能存在会永久丢失内存的 malloc()/free() 不匹配,即即使在进程完成之后?
不,malloc和free,甚至mmap在这方面是无害的,当进程终止时,操作系统(在本例中为 SUSE Linux)会收回所有内存(除非它与仍在运行的其他进程共享)。
C 程序(不是 C++)中还有哪些其他东西会导致永久性内存丢失,即在程序完成后,甚至终端窗口关闭?只有重新启动才能恢复内存。我已经阅读了其他关于文件未关闭导致问题的帖子,但是,我认为我没有这个问题。
与 malloc/free 和 mmap 一样,进程打开的文件会被操作系统自动关闭。
有一些事情会导致永久内存泄漏,例如大页面,但如果您使用它们,您肯定会知道。除此之外,没有。
但是,如果您将内存丢失定义为未立即标记为“空闲”的内存,则可能会发生一些情况。
请注意,作为为我所有 RAM 付费的人,我宁愿操作系统一直使用它,如果它以最小的方式提供帮助。空闲 RAM 是浪费的 RAM。
空闲 RAM 很少的主要问题是当它被过度使用时,也就是说,现在请求或使用 RAM 的进程(和操作系统)比系统上可用的要多。听起来你在你的进程中使用了大约 4Gb 的 RAM,这可能是一个问题 - (记住操作系统也需要一个很好的块。但听起来你有足够的 RAM!尝试运行一半的进程,看看如果它变得更好。
有时内存泄漏会导致暂时的过度使用 - 调查一下是个好主意。尝试绘制程序随时间的内存使用情况 - 如果它持续上升,则很可能是泄漏。
请注意,forking 一个进程会创建一个副本,该副本共享原始分配的内存 - 直到两者都关闭或其中一个'exec's。但你不会那样做。
查看 top 和 free 的内存统计数据是否有效,即它们是否准确地描述了内存情况?它们似乎确实与程序的缓慢相对应。
是的,top并且ps是查看内存的完全合理的方法,特别是观察 RES 字段。暂时忽略 VIRT 字段。此外:
要查看整个系统使用内存做什么,请运行:
vmstat 10
Run Code Online (Sandbox Code Playgroud)
在您的程序运行一段时间后。看看---memory---列会发生什么。
此外,在您的进程完成后,运行
cat /proc/meminfo
Run Code Online (Sandbox Code Playgroud)
并在您的问题中发布结果。
如果程序只显示4%的内存使用率,valgrind之类的会发现这个问题吗?
可能,但它可能非常慢,在这种情况下可能不切实际。还有很多其他工具可以提供帮助,例如电栅栏和其他不会显着降低程序速度的工具。过去我什至自己动手。