【问题标题】:How can I programmatically get the amount of memory currently available from C/C++ code?如何以编程方式从 C/C++ 代码中获取当前可用的内存量?
【发布时间】:2011-06-28 06:58:04
【问题描述】:

在我的中间件软件层中,由于该消息,我收到了很多崩溃,

page allocation failure. order:10, mode:0xd1

据我了解,崩溃的发生可能有多种原因,例如动态内存不足以进行进一步分配或内存碎片。

消息后面的回溯不相关,因为它来自第三方驱动程序模块,很可能问题出在该驱动程序上,但不幸的是,我既无法从中获得任何调试信息,也无法获得源代码。我想使用一些编程函数调用来分析我的源代码,以排除我上面提到的两种情况的可能性。

我无法使用 valgrind,因为 Valgrind 尚未完全支持 ARM。

[更新:] 添加堆栈跟踪,正如@caf 的回答所暗示的那样,其中可能包含一些有价值的信息。

Application: page allocation failure. order:10, mode:0xd1
Backtrace:                                                  
[<c00297d0>] (dump_backtrace+0x0/0x114) from [<c02812b8>] (dump_stack+0x18/0x1c)
 r7:0000000a r6:000000d1 r5:00000000 r4:00000000                                
[<c02812a0>] (dump_stack+0x0/0x1c) from [<c00716e4>] (__alloc_pages_nodemask+0x49c/0x4fc)
[<c0071248>] (__alloc_pages_nodemask+0x0/0x4fc) from [<c007175c>] (__get_free_pages+0x18/0x44)
[<c0071744>] (__get_free_pages+0x0/0x44) from [<bf021790>] (tsif_request_rx_buffer+0x74/0xf4 [tsif_data])
[<bf02171c>] (tsif_request_rx_buffer+0x0/0xf4 [tsif_data]) from [<bf021bd8>] (tsif_data_ioctl+0x17c/0x9d4 [tsif_data])
 r7:be9e8604 r6:c0045319 r5:c3793400 r4:00000007
[<bf021a5c>] (tsif_data_ioctl+0x0/0x9d4 [tsif_data]) from [<c00a1c30>] (vfs_ioctl+0x78/0x94)
[<c00a1bb8>] (vfs_ioctl+0x0/0x94) from [<c00a22e0>] (do_vfs_ioctl+0x594/0x5f0)
 r7:c2067e80 r6:00000021 r5:c2067e80 r4:00000021
[<c00a1d4c>] (do_vfs_ioctl+0x0/0x5f0) from [<c00a237c>] (sys_ioctl+0x40/0x64)
[<c00a233c>] (sys_ioctl+0x0/0x64) from [<c0025ec0>] (ret_fast_syscall+0x0/0x28)
 r7:00000036 r6:00144220 r5:00139030 r4:008a47cc
Mem-info:
DMA per-cpu:
CPU    0: hi:   18, btch:   3 usd:   0
active_anon:4120 inactive_anon:134 isolated_anon:0
 active_file:79 inactive_file:3729 isolated_file:0
 unevictable:0 dirty:0 writeback:0 unstable:0 buffer:0
 free:4137 slab_reclaimable:198 slab_unreclaimable:894
 mapped:1707 shmem:64 pagetables:75 bounce:0
DMA free:16548kB min:1104kB low:1380kB high:1656kB active_anon:16480kB inactive_anon:536kB active_file:316kB inactive_file:14916kB unevictable:0kB isolated(o
lowmem_reserve[]: 0 0 0
DMA: 215*4kB 131*8kB 73*16kB 49*32kB 30*64kB 8*128kB 3*256kB 2*512kB 3*1024kB 2*2048kB 0*4096kB 0*8192kB 0*16384kB = 16548kB
3872 total pagecache pages
19200 pages of RAM
4209 free pages
4738 reserved pages
960 slab pages
1751 pages shared
0 pages swap cached

所以问题是如何以编程方式从 C/C++ 代码中获取当前可用的内存量,平台是 Linux。

【问题讨论】:

  • man 2 getrlimit 呢?
  • 如果你想要安装物理内存的数量,你可以解析/proc/meminfo的第一行
  • @Victor Sorokin:getrlimit,获取系统资源的限制,而不是当前可用的数量。
  • @Als 然后你解析/proc/meminfo的第二行:)
  • 您是否考虑过将值 -1 转换为无符号然后用作分配金额的可能性?

标签: c++ c linux embedded-linux


【解决方案1】:

您显示的消息表明未能为内核分配而不是用户空间分配分配内存。这是对 4MB(这是order = 10 的意思)连续物理内存块的请求。这是一个非常大的kmalloc() 请求,它失败并不奇怪(可能是由于内存碎片而不是空闲内存)。

您可以在/proc/meminfo 中了解有多少可用内存,但是更详细的摘要可以从内核日志中立即获得 回溯- 从"Mem-info" 行开始。


您的回溯显示有 16548kB 的可用内存,但最大的块是 2048kB (order = 9)。所以内存碎片确实是你的问题。

从阅读您似乎正在使用的source to the tsif driver 来看,似乎驱动程序请求了一个大小完全由用户空间控制的内核分配,由TSIF_REQ_RX_BUF ioctl() 调用(这是一个真的 糟糕的设计,特别是考虑到它甚至没有尝试向用户空间报告失败!)。我的建议是使用 ioctl 减少您请求的缓冲区大小。

【讨论】:

  • 我更新了有问题的附加信息,有什么问题大家可以指出来。
  • 谢谢!优秀的答案!不幸的是,改变这个巨大的分配对我来说不是一个可行的选择,但你的回答给了我方向。发生的事情是,在应用程序的生命周期中,ioctl TSIF_REQ_RX_BUF 被多次调用和释放,这用于进一步分割内存。我解决的方法是在应用程序生命周期开始时调用 ioctl 一次,我确信它会成功(因为当时碎片较少)然后在应用程序的整个生命周期中使用它,然后在结束时发布终生。
猜你喜欢
  • 2020-07-30
  • 1970-01-01
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
  • 2011-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多