我目前正在处理的一些程序消耗的内存比我认为的要多得多。所以我想了解 glibc malloc 修剪是如何工作的。我写了以下测试:
#include <malloc.h>
#include <unistd.h>
#define NUM_CHUNKS 1000000
#define CHUNCK_SIZE 100
int main()
{
// disable fast bins
mallopt(M_MXFAST, 0);
void** array = (void**)malloc(sizeof(void*) * NUM_CHUNKS);
// allocating memory
for(unsigned int i = 0; i < NUM_CHUNKS; i++)
{
array[i] = malloc(CHUNCK_SIZE);
}
// releasing memory ALMOST all memory
for(unsigned int i = 0; i < NUM_CHUNKS - 1 ; i++)
{
free(array[i]);
}
// when enabled memory consumption reduces
//int ret = malloc_trim(0);
//printf("ret=%d\n", ret);
malloc_stats();
sleep(100000);
}
测试输出(不调用 malloc_trim):
Arena 0:
system bytes = 112054272
in use bytes = 112
Total (incl. mmap):
system bytes = 120057856
in use bytes = 8003696
max mmap regions = 1
max mmap bytes = 8003584
尽管几乎所有内存都已释放,但此测试代码消耗的常驻内存比预期的要多得多:
[root@node0-b3]# ps aux | grep test
root 14662 1.8 0.4 129736 **118024** pts/10 S 20:19 0:00 ./test
过程图:
0245e000-08f3b000 rw-p 00000000 00:00 0 [heap]
Size: 109428 kB
Rss: 109376 kB
Pss: 109376 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 109376 kB
Referenced: 109376 kB
Anonymous: 109376 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr mr mw me ac
7f1c60720000-7f1c60ec2000 rw-p 00000000 00:00 0
Size: 7816 kB
Rss: 7816 kB
Pss: 7816 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 7816 kB
Referenced: 7816 kB
Anonymous: 7816 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
当我启用对 malloc_trim 的调用时,测试的输出几乎保持不变:
ret=1
Arena 0:
system bytes = 112001024
in use bytes = 112
Total (incl. mmap):
system bytes = 120004608
in use bytes = 8003696
max mmap regions = 1
max mmap bytes = 8003584
然而,RSS 明显下降:
[root@node0-b3]# ps aux | grep test
root 15733 0.6 0.0 129688 **8804** pts/10 S 20:20 0:00 ./test
处理 smap(在 malloc_trim 之后):
01698000-08168000 rw-p 00000000 00:00 0 [heap]
Size: 109376 kB
Rss: 8 kB
Pss: 8 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 8 kB
Referenced: 8 kB
Anonymous: 8 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr mr mw me ac
7f508122a000-7f50819cc000 rw-p 00000000 00:00 0
Size: 7816 kB
Rss: 7816 kB
Pss: 7816 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 7816 kB
Referenced: 7816 kB
Anonymous: 7816 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
调用 malloc_trim 后,堆变小了。我假设 8MB mmap 段仍然可用,因为最后一 block 内存没有被释放。
为什么 malloc 不自动执行堆修剪? 有没有办法配置 malloc 以便自动完成修剪(当它可以节省那么多内存时)?
我使用的是 glibc 2.17 版。
最佳答案
主要是出于历史原因,小分配的内存来自由 brk 管理的池系统调用。这是一个非常古老的系统调用——至少与Version 6 Unix一样古老— 它唯一能做的就是改变内存中位置固定的“竞技场”的大小。这意味着,brk 池不能缩小超过仍分配的 block 。
你的程序分配了 N 个内存块,然后释放了其中的 N-1 个。它不会释放的一个 block 是位于最高 地址的 block 。这是 brk 的最坏情况:即使 99.99% 的池未使用,大小也根本无法减少!如果您更改您的程序,使其未释放的 block 是 array[0] 而不是 array[NUM_CHUNKS-1],您应该同时看到 RSS 和地址空间在最后一次调用 free 时收缩。
当您显式调用 malloc_trim 时,它会尝试使用 Linux 扩展来解决此限制,madvise(MADV_DONTNEED) ,它会释放物理 RAM,但不会释放地址空间(正如您观察到的那样)。我不知道为什么这只会在显式调用 malloc_trim 时发生。
顺便说一句,8MB 的 mmap 段用于您初始分配 array。
关于linux - 了解 glibc malloc 修剪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38644578/
我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject
是否有self验证的问题列表。看着那个,我可以确定我知道。我应该复习一下。在学习的过程中,我列了一个这样的list,但它只包含我在某处听说过的项目。我需要一段时间才能找到新的东西。 最佳答案 以下是针对ruby和Rails的一些测试列表。证书名称:RubyonRails谁提供:oDeskIncorporation认证费用:免费网站:https://www.odesk.com/tests/985?pos=0证书名称:RubyonRails提供者:Techgig.com(TimesBusinessSolutionsLimited(T
我想覆盖store_accessor的getter。可以查到here.代码在这里:#Fileactiverecord/lib/active_record/store.rb,line74defstore_accessor(store_attribute,*keys)keys=keys.flatten_store_accessors_module.module_evaldokeys.eachdo|key|define_method("#{key}=")do|value|write_store_attribute(store_attribute,key,value)enddefine_met
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?
Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好
文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我一直在Rails上做两个项目,它们运行良好,但在这个过程中重新发明了轮子,自来水(和热水)和止痛药,正如我随后了解到的那样,这些已经存在于框架中。那么基本上,正确了解框架中所有智能部分的最佳方法是什么,这将节省时间而不是自己构建已经实现的功能?从第1页开始阅读文档?是否有公开所有内容的特定示例应用程序?一个特定的开源项目?所有的rails交通?还是完全
如何在Ruby中获取linux系统(这必须适用于Fedora、Ubuntu等)的软件/硬件信息? 最佳答案 Chef背后的优秀人才,拥有一颗名为Ohai的优秀gemhttps://github.com/opscode/ohai以散列形式返回系统信息,例如操作系统、内核、规范、fqdn、磁盘、空间、内存、用户、接口(interface)、sshkey等。它非常完整,非常好。它还会安装命令行二进制文件(也称为ohai)。 关于ruby-如何在Ruby中获取linux系统信息,我们在Stack
我在LinuxMint17.2上。我最近使用apt-getpurgeruby删除了ruby。然后我安装了rbenv然后rbenvinstall2.3.0所以现在,~/.rbenv/versions/2.3.0/bin/ruby存在。但是现在,我无法执行geminstallrubocop。我明白了:$geminstallrubocoprbenv:gem:commandnotfoundThe`gem'commandexistsintheseRubyversions:2.3.0但是我可以~/.rbenv/versions/2.3.0/bin/geminstallrubocop。但是,
假设我有一个函数defodd_or_evennifn%2==0return:evenelsereturn:oddendend我有一个简单的可枚举数组simple=[1,2,3,4,5]然后我用我的函数在map中运行它,使用一个do-endblock:simple.mapdo|n|odd_or_even(n)end#=>[:odd,:even,:odd,:even,:odd]如果不首先定义函数,我怎么能做到这一点?例如,#doesnotworksimple.mapdo|n|ifn%2==0return:evenelsereturn:oddendend#Desiredresult:#=>[