物理内存占用过高还有很多,为什么会占用swap分区

1328人阅读
Linux(7)
转自&/linux/Linuxxiaruheshifangnacun_swapfenqumanliaozenmeban__111.html
在Linux系统下,我们一般不需要去释放内存,因为系统已经将内存管理的很好。但是凡事也有例外,有的时候内存会被缓存占用掉,导致系统使用SWAP空间影响性能,此时就需要执行释放内存(清理缓存)的操作了。
Linux系统的缓存机制是相当先进的,他会针对dentry(用于VFS,加速文件路径名到inode的转换)、Buffer Cache(针对磁盘块的读写)和Page Cache(针对文件inode的读写)进行缓存操作。但是在进行了大量文件操作之后,缓存会把内存资源基本用光。但实际上我们文件操作已经完成,这部分缓存已经用不到了。这个时候,我们难道只能眼睁睁的看着缓存把内存空间占据掉么?
关于内存耗尽的总结:
1)在进程收到OOM之前,内核将刷新文件系统的cache来释放空间.
2)将交换区的页面移到磁盘上.
3)当内存变少时,虚拟性使每个进程通过交换区来做简单的上下文环境切换.
4)当进程消耗尽交换内存后,才会引发out-of-memory(OOM)来kill那些进程.
所以,我们还是有必要来手动进行Linux下释放内存的操作,其实也就是释放缓存的操作了。
要达到释放缓存的目的,我们首先需要了解下关键的配置文件/proc/sys/vm/drop_caches。这个文件中记录了缓存释放的参数,默认值为0,也就是不释放缓存。他的值可以为0~3之间的任意数字,代表着不同的含义:
0 – 不释放
1 – 释放页缓存
2 – 释放dentries和inodes
3 – 释放所有缓存
知道了参数后,我们就可以根据我们的需要,使用下面的指令来进行操作。
首先我们需要使用sync指令,将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件。否则在释放缓存的过程中,可能会丢失未保存的文件。
接下来,我们需要将需要的参数写进/proc/sys/vm/drop_caches文件中,比如我们需要释放所有缓存,就输入下面的命令:
#echo 3 & /proc/sys/vm/drop_caches
此指令输入后会立即生效,可以查询现在的可用内存明显的变多了。
要查询当前缓存释放的参数,可以输入下面的指令:
#cat /proc/sys/vm/drop_caches
swap的概述
swap的作用可简单描述为:
当内存不够用时,将存储器中的数据块从DRAM移到swap的磁盘空间中,以释放更多的空间给当前进程使用.
当再次需要那些数据时,就可以将swap磁盘中的数据重新移到内存,而将那些不用的数据块从内存移到swap中.
2)数据从内存移动交换区的行为被称为页面调用,发生在后台的页面调用没有来自应用程序的干涉.
3)swap空间是分页的,每一页的大小和内存页的大小一样.
4)并不是一定要给每个系统划分SWAP,比如大多数的嵌入式就没有swap.
##在执行以上操作以后,查看你的swap分区还是满了,你首先查看一下你实际的内存剩多少空间,然后在查看自己的swap空间用了多少,首先提前保证实际剩余的内存比你的swap的内存的空间要大,然后执行一下操作,否则会宕机的!
首先我们停掉swap分区,查看swap分区
swapon -s 会查看到你的swap分区是挂在哪里!
然后比如说我的是挂到/dev/sda2
swapoff & /dev/sda2
停止是需要一段时间的,因为他会把内存释放到实际内存当中,
然后在启动我们的swap分区
我们的swap分区内存已经成功释放到了实际内存当中!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:5073次
排名:千里之外
原创:19篇
(1)(14)(7)(2)(3)(1)|||||||||||||||||
查看: 8199|回复: 38
在线时间2364 小时经验值16839 最后登录注册时间帖子阅读权限100UID1450027
TA的每日心情慵懒 15:03签到天数: 5 天[LV.2]偶尔看看I
G币777 最后登录注册时间
本帖最后由 wmjan 于
18:58 编辑
发现虚拟机分区完成,格式化好以后,右键点击SWAP分区,有“启用交换分区”选项,显然默认是“禁用交换分区”,这一点O大从来没有说明过。。。。
今天尝试了在“启用交换分区”和“禁用交换分区”两种方式下查看swap均占用为0
超级终端里输入:su 回车
& && && && && &free 回车
谢谢O大的回复!
————————————————————————————————————————————————————————
终于看到swap占用的时候了:说明刷O大ROM,swap分区还是有必要的。O大3.9.8时就说明了:没有交换分区会增加程序被杀死和载入的几率!
18:35 上传
18:50 上传
在线时间133 小时经验值134 最后登录注册时间帖子阅读权限40UID509552
高中生, 积分 134, 距离下一级还需 66 积分
该用户从未签到
G币65 最后登录注册时间
大家技术上多讨论,比吹嘘拍马的好多了…
在线时间878 小时经验值507 最后登录注册时间帖子阅读权限60UID641608
大学本科, 积分 507, 距离下一级还需 193 积分
该用户从未签到
G币667 最后登录注册时间
你试试打开几个软件再看看swap...
貌似O大说分100M的swap我从来用不到10m
Winnie WinX
在线时间2364 小时经验值16839 最后登录注册时间帖子阅读权限100UID1450027
TA的每日心情慵懒 15:03签到天数: 5 天[LV.2]偶尔看看I
G币777 最后登录注册时间
我也特意打开好几个软件再查看的
在线时间3803 小时经验值19892 最后登录注册时间帖子阅读权限180UID535399
院士, 积分 19892, 距离下一级还需 1108 积分
该用户从未签到
G币6158 最后登录注册时间
首先&&发现虚拟机分区完成,格式化好以后,右键点击SWAP分区,有“启用交换分区”选项,显然默认是“禁用交 ...
wmjan 发表于
& &第四个分区是交换分区,如果你只分了3个或者2个就不会启用。
手机中启用交换分区和你在虚拟机里启用是完全风马牛不相及的事情,你在虚拟机里边“启用交换分区”的意思是:把你临时杵在虚拟机里边的SD卡的那个交换分区用于整个虚拟机的交换分区。不仅与手机是否启用交换分区无关,而且估计会极大减少你SD卡的使用寿命(考虑到肯定只是临时插在虚拟机上,所以应该无所谓的)
在线时间146 小时经验值120 最后登录注册时间帖子阅读权限40UID1514743
高中生, 积分 120, 距离下一级还需 80 积分
该用户从未签到
G币481 最后登录注册时间
顶,,,同问。。
成都 G7 机油
在线时间133 小时经验值134 最后登录注册时间帖子阅读权限40UID509552
高中生, 积分 134, 距离下一级还需 66 积分
该用户从未签到
G币65 最后登录注册时间
谢谢大大……
在线时间2364 小时经验值16839 最后登录注册时间帖子阅读权限100UID1450027
TA的每日心情慵懒 15:03签到天数: 5 天[LV.2]偶尔看看I
G币777 最后登录注册时间
谢谢老大的解答。。
在线时间2364 小时经验值16839 最后登录注册时间帖子阅读权限100UID1450027
TA的每日心情慵懒 15:03签到天数: 5 天[LV.2]偶尔看看I
G币777 最后登录注册时间
自己再顶顶
在线时间382 小时经验值282 最后登录注册时间帖子阅读权限50UID91566
大学专科, 积分 282, 距离下一级还需 118 积分
TA的每日心情无聊 23:04签到天数: 2 天[LV.1]初来乍到
G币199 最后登录注册时间
刚刷完O大的4.0,刚才也查看了交换分区的情况,怎么显示为零啊?我还专门打开了几个程序。
我给交换分区的空间是300兆,如下图所示:
20:42 上传
浏览过的版块
Powered by博客访问: 218627
博文数量: 88
博客积分: 2088
博客等级: 大尉
技术积分: 678
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
/home-space-do-blog-uid-56821-id-149454.html
《swap分区与内存耗尽》
已有 1294 次阅读
|关键词:swap 内存 应用 系统 LINUX 用户 内核 Swap overcommit Linux ulimit setrlimit
一)swap的概述
1)swap的作用可简单描述为:当内存不够用时,将存储器中的数据块从DRAM移到swap的磁盘空间中,以释放更多的空间给当前进程使用.当再次需要那些数据时,就可以将swap磁盘中的数据重新移到内存,而将那些不用的数据块从内存移到swap中.
2)数据从内存移动交换区的行为被称为页面调用,发生在后台的页面调用没有来自应用程序的干涉.
3)swap空间是分页的,每一页的大小和内存页的大小一样.
4)并不是一定要给每个系统划分SWAP,比如大多数的嵌入式就没有swap.
二)swap能让系统最多使用多少内存?
一个32位的LINUX系统在没有启用PAE的情况下最多可以用4GB的物理内存.在用户空间中最多可用3GB.而增加swap会让系统增加可使用的内存空间吗?
用下面的测试回答这个问题:
查看内核版本[root@test1 tmp]# uname -r2.6.18-8.el5建一个10GB的文件[root@test1 tmp]# dd if=/dev/zero f=data.dat bs=10M count=1000
[root@test1 tmp]# mkswap data.dat Setting up swapspace version 1, size =
[root@test1 tmp]# free -m&&&&&&&&&&&& total&&&&&& used&&&&&& free&&&& shared&&& buffers&&&& cachedMem:&&&&&&&&&& 503&&&&&&&& 43&&&&&&& 460&&&&&&&&& 0&&&&&&&& 13&&&&&&&&& 9-/+ buffers/cache:&&&&&&&& 20&&&&&&& 482Swap:&&&&&&&& 1027&&&&&&&& 22&&&&&& 1005
[root@test1 tmp]# swapon data.dat
[root@test1 tmp]# free -m&&&&&&&&&&&& total&&&&&& used&&&&&& free&&&& shared&&& buffers&&&& cachedMem:&&&&&&&&&& 503&&&&&&&& 46&&&&&&& 457&&&&&&&&& 0&&&&&&&& 15&&&&&&&&& 9-/+ buffers/cache:&&&&&&&& 20&&&&&&& 482Swap:&&&&&&& 11027&&&&&&&& 22&&&&& 11005
[root@test1 tmp]# swapon -s Filename&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Type&&&&&&&&&&& Size&&& Used&&& Priority/dev/sda2&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& partition&&&&&& 40&& -1/tmp/data.dat&&&&&&&&&&&&&&&&&&&&&&&&&& file&&&&&&&&&&& &&&&&&& 0&&&&&& -3
现在的物理内存和swap加起来超过了4GB.而我们最多能用多少呢?
下面的程序会不断申请/分配内存空间.源程序如下:test1#include #include #include
int main (int argc, char *argv[]){&&&&&&& void *&&&&&&& int n = 0;&&&&&&& while (1){&&&&&&&&&&&&&&& ptr = malloc(0x100000);
&&&&&&&&&&&&&&& if (ptr == NULL)&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&& memset(ptr, 1, 0x100000);&&&&&&&&&&&&&&& printf("malloced %d MB\n", ++n);&&&&&&& }
&&&&&&& pause();}
[root@test1 tmp]# gcc test1.c -o callmem[root@test1 tmp]# ./callmem
malloced 3039 MBmalloced 3040 MBmalloced 3041 MBmalloced 3042 MBmalloced 3043 MBmalloced 3044 MBmalloced 3045 MBmalloced 3046 MBmalloced 3047 MBmalloced 3048 MBmalloced 3049 MBmalloced 3050 MBmalloced 3051 MBmalloced 3052 MBmalloced 3053 MBmalloced 3054 MBmalloced 3055 MBmalloced 3056 MB
在分配了3056MB的内存之后,再不能分配了,说明即使通过swap给系统增加了10GB的内存,系统最终也只能使用3056MB的内存空间(用户空间),不能突破4GB的限制.
三)超过了系统最大可使用内存空间会怎样?
依旧是上面的例子,我们关闭掉swap文件data.dat
[root@test1 tmp]# swapoff data.dat
查看当前的swap空间[root@test1 tmp]# swapon -s Filename&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Type&&&&&&&&&&& Size&&& Used&&& Priority/dev/sda2&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& partition&&&&&& 60&& -1
执行callmem[root@test1 tmp]# ./callmem
malloced 1465 MBmalloced 1466 MBmalloced 1467 MBmalloced 1468 MBmalloced 1469 MBmalloced 1470 MBmalloced 1471 MBmalloced 1472 MBmalloced 1473 MBmalloced 1474 MBmalloced 1475 MBmalloced 1476 MBmalloced 1477 MBmalloced 1478 MBmalloced 1479 MBmalloced 1480 MBmalloced 1481 MBmalloced 1482 MBmalloced 1483 MBmalloced 1484 MBmalloced 1485 MBKilled
在分配了1485MB内存后,程序退出.
在/var/log/message中查看报错的信息,如下:
May 30 10:40:52 test1 kernel: automount invoked oom-killer: gfp_mask=0x201d2, rder=0, mkilladj=0May 30 10:40:52 test1 kernel:& [] out_of_memory+0x3b/0x179May 30 10:40:52 test1 kernel:& [] __alloc_pages+0x1fe/0x27eMay 30 10:40:52 test1 kernel:& [] __do_page_cache_readahead+0xc4/0x1c6May 30 10:40:52 test1 kernel:& [] sync_page+0x0/0x3bMay 30 10:40:52 test1 kernel:& [] __delayacct_blkio_end+0x32/0x35May 30 10:40:52 test1 kernel:& [] __wait_on_bit_lock+0x4b/0x52May 30 10:40:52 test1 kernel:& [] __lock_page+0x51/0x57May 30 10:40:52 test1 kernel:& [] filemap_nopage+0x151/0x315May 30 10:40:52 test1 kernel:& [] __handle_mm_fault+0x172/0x87bMay 30 10:40:52 test1 kernel:& [] __activate_task+0x1c/0x29May 30 10:40:52 test1 kernel:& [] wake_up_new_task+0x1be/0x1c6May 30 10:40:52 test1 kernel:& [] do_page_fault+0x20a/0x4b8May 30 10:40:52 test1 kernel:& [] do_page_fault+0x0/0x4b8May 30 10:40:52 test1 kernel:& [] error_code+0x39/0x40May 30 10:40:52 test1 kernel:& =======================May 30 10:40:52 test1 kernel: Mem-info:May 30 10:40:52 test1 kernel: DMA per-cpu:May 30 10:40:52 test1 kernel: cpu 0 hot: high 0, batch 1 used:0May 30 10:40:52 test1 kernel: cpu 0 cold: high 0, batch 1 used:0May 30 10:40:52 test1 kernel: DMA32 per-cpu: emptyMay 30 10:40:52 test1 kernel: Normal per-cpu:May 30 10:40:52 test1 kernel: cpu 0 hot: high 186, batch 31 used:30May 30 10:40:52 test1 kernel: cpu 0 cold: high 62, batch 15 used:14May 30 10:40:52 test1 kernel: HighMem per-cpu: emptyMay 30 10:40:52 test1 kernel: Free pages:&&&&&&& 4844kB (0kB HighMem)May
30 10:40:52 test1 kernel: Active:62495 inactive:62136 dirty:0
writeback:4 unstable:0 free:1211 slab:1350 mapped:0 pagetables:693May
30 10:40:52 test1 kernel: DMA free:2072kB min:88kB low:108kB high:132kB
active:5108kB inactive:5084kB present:16384kB pages_scanned:15907 all_unreclaimable? yesMay 30 10:40:52 test1 kernel: lowmem_reserve[]: 0 0 496 496May
30 10:40:52 test1 kernel: DMA32 free:0kB min:0kB low:0kB high:0kB
active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? noMay 30 10:40:52 test1 kernel: lowmem_reserve[]: 0 0 496 496May
30 10:40:52 test1 kernel: Normal free:2772kB min:2804kB low:3504kB
high:4204kB active:244872kB inactive:243460kB present:507904kB pages_scanned:990188 all_unreclaimable? yesMay 30 10:40:52 test1 kernel: lowmem_reserve[]: 0 0 0 0May
30 10:40:52 test1 kernel: HighMem free:0kB min:128kB low:128kB
high:128kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? noMay 30 10:40:52 test1 kernel: lowmem_reserve[]: 0 0 0 0May 30 10:40:52 test1 kernel: DMA: 0*4kB 1*8kB 1*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 1*2048kB 0*4096kB = 2072kBMay 30 10:40:52 test1 kernel: DMA32: emptyMay
30 10:40:52 test1 kernel: Normal: 1*4kB 0*8kB 3*16kB 1*32kB 0*64kB
1*128kB 0*256kB 1*512kB 0*1024kB 1*2048kB 0*4096kB = 2772kBMay 30 10:40:52 test1 kernel: HighMem: emptyMay 30 10:40:52 test1 kernel: Swap cache: add 2790571, delete 2790571, find , race 2+1May 30 10:40:53 test1 kernel: Free swap& = 0kBMay 30 10:40:53 test1 kernel: Total swap = 1052248kBMay 30 10:40:53 test1 kernel: Free swap:&&&&&&&&&&& 0kBMay 30 10:40:53 test1 kernel: 131072 pages of RAMMay 30 10:40:53 test1 kernel: 0 pages of HIGHMEMMay 30 10:40:53 test1 kernel: 2188 reserved pagesMay 30 10:40:53 test1 kernel: 59 pages sharedMay 30 10:40:53 test1 kernel: 0 pages swap cachedMay 30 10:40:53 test1 kernel: 0 pages dirtyMay 30 10:40:53 test1 kernel: 4 pages writebackMay 30 10:40:53 test1 kernel: 0 pages mappedMay 30 10:40:53 test1 kernel: 1350 pages slabMay 30 10:40:53 test1 kernel: 693 pages pagetablesMay 30 10:40:53 test1 kernel: Out of memory: Killed process 2720 (callmem)
通过测试证明在程序申请了多于系统的内存可使用空间时,程序将被中止.同时系统将回收这个程序已申请分配的内存空间.
四)关于内存耗尽的总结:
1)在进程收到OOM之前,内核将刷新文件系统的cache来释放空间.2)将交换区的页面移到磁盘上.3)当内存变少时,虚拟性使每个进程通过交换区来做简单的上下文环境切换.4)当进程消耗尽交换内存后,才会引发out-of-memory(OOM)来kill那些进程.
五)内存耗尽的解决办法
有三种方法解决进程对内存的疯狂占用.
1)overcommit
当系统用完RAM和交换区后,内核将终止响应进程,malloc持续地返回远大于系统所能提供的指向虚拟地址的指针,Linux称这种情况为overcommit.overcommit默认是0,处于开启状态,允许一个进程分配多于当前可用的内存,而进程耗尽可用内存时,将被OOM(out-of-memroy)终止.可以人为将overcommit改为2,即关闭covercommit,它迫使内核在分配内存时,是基于当前可用的物理内存.
通过下面的程序测试malloc和overcommit,这个程序与之前的程序最大不同是,程序只分配内存(malloc),但不通过memset来修改它申请的数据,这样就不会产生缺页.
源程序如下:test2#include #include #include
intmain (int argc, char *argv[]){&&&&&&& void *&&&&&&& int n = 0;&&&&&&& while (1){&&&&&&&&&&&&&&& ptr = malloc(0x100000);&&&&&&&&&&&&&&& if (ptr == NULL)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& n++;&&&&&&& }
&&&&&&& printf("malloced %d MB\n", n);&&&&&&& pause();}
现在overcommit处于开启状态:[root@test1 ~]# cat /proc/sys/vm/overcommit_memory 0
为便于测试将swap分区内存关闭:[root@test1 tmp]# swapoff -a
编译程序test2.c[root@test1 tmp]# gcc test2.c -o callmem1
执行callmem1,发现它申请了3056MB,而物理内存只有512MB.[root@test1 tmp]# ./callmem1 malloced 3056 MB
现在关闭overcommit[root@test1 tmp]# echo 2 > /proc/sys/vm/overcommit_memory
[root@test1 tmp]# free&&&&&&&&&&&& total&&&&&& used&&&&&& free&&&& shared&&& buffers&&&& cachedMem:&&&&&&& 515600&&&&& 49624&&&& 465976&&&&&&&&& 0&&&&&& 1464&&&&& 14908-/+ buffers/cache:&&&&& 33252&&&& 482348Swap:&&&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0
再次执行callmem1,发现它这回只申请到了182MB的内存.[root@test1 tmp]# ./callmem1 malloced 182 MB
malloc只会分配内存,它没有修改数据,所以并不用占用内存空间.通过free命令查看后没有明显变化.[root@test1 tmp]# free&&&&&&&&&&&& total&&&&&& used&&&&&& free&&&& shared&&& buffers&&&& cachedMem:&&&&&&& 515600&&&&& 50244&&&& 465356&&&&&&&&& 0&&&&&& 1472&&&&& 14908-/+ buffers/cache:&&&&& 33864&&&& 481736Swap:&&&&&&&&&&& 0&&&&&&&&& 0&&&&&&&&& 0
通过ulimit系统命令限制当前shell只能用10MB的内存资源.[root@test1 tmp]# ulimit -d 10240 -m 10240 -v 10240
-d&&&& The maximum size of a process data segment-m&&&& The maximum resident set size-v&&&& The maximum amount of virtual memory available to the shell
其中-v是决定性的,它决定了当前shell可用的最多虚拟内存.
检查设置的结果[root@test1 tmp]# ulimit -acore file size&&&&&&&&& (blocks, -c) 0data seg size&&&&&&&&&& (kbytes, -d) 10240max nice&&&&&&&&&&&&&&&&&&&&&&& (-e) 0file size&&&&&&&&&&&&&& (blocks, -f) unlimitedpending signals&&&&&&&&&&&&&&&& (-i) 8192max locked memory&&&&&& (kbytes, -l) 32max memory size&&&&&&&& (kbytes, -m) 10240open files&&&&&&&&&&&&&&&&&&&&& (-n) 1024pipe size&&&&&&&&&&& (512 bytes, -p) 8POSIX message queues&&&& (bytes, -q) 819200max rt priority&&&&&&&&&&&&&&&& (-r) 0stack size&&&&&&&&&&&&& (kbytes, -s) 10240cpu time&&&&&&&&&&&&&& (seconds, -t) unlimitedmax user processes&&&&&&&&&&&&& (-u) 8192virtual memory&&&&&&&&& (kbytes, -v) 10240file locks&&&&&&&&&&&&&&&&&&&&& (-x) unlimited
最后执行callmem1[root@test1 tmp]# ./callmem1&[1] 2525malloced 8 MB我们限制到了10MB,为什么只能分配8MB的内存.
用pmap查看映射地址.[root@test1 tmp]# jobs -x pmap %12525:&& ./callmem1&& 1244K r-x--& /lib/libc-2.5.so&&&&& 8K r-x--& /lib/libc-2.5.so&&&&& 4K rwx--& /lib/libc-2.5.so&&&& 12K rwx--&&& [ anon ]00b51000&&& 100K r-x--& /lib/ld-2.5.so00b6a000&&&&& 4K r-x--& /lib/ld-2.5.so00b6b000&&&&& 4K rwx--& /lib/ld-2.5.so00c68000&&&&& 4K r-x--&&& [ anon ]&&&&& 4K r-x--& /tmp/callmem1&&&&& 4K rw---& /tmp/callmem1b7777000&& 8228K rw---&&& [ anon ]b7f93000&&&&& 8K rw---&&& [ anon ]bfe56000&&&& 88K rw---&&& [ stack ]&total&&&& 9712K
我们看到除了程序自身malloc分配掉的内存之外,还分别加载了动态链接库libc-2.5.so,ld-2.5.so.在通过malloc分配了8228KB时,程序已经不能再申请1MB的内存了.
3)setrlimit
我们在实际应用的过程式中,可以通过sysconf(_SC_AVPHYS_PAGES);获取系统中可用物理内存页的数量.而不包括刷新的cache和交换到磁盘上的空间.它和MemFree的值很相近.可以通过/proc/meminfo查看.这个值应该说是一个很保存的值,因为它不包括通过刷新为人所知cache而释放的空间.
我们通过setrlimit系统调用,来保证当前进程只能使用sysconf(_SC_AVPHYS_PAGES)获得保守值.
第一步去掉上一个试验留下的内存限制.[root@test1 tmp]# ulimit -d unlimited -m unlimited -v unlimited
编译test3.c[root@test1 tmp]# gcc test3.c -o callmem2
源程序如下:test3.c#include #include #include #include #include #include #include #include #include
intmain (int argc, char *argv[]){&&&&&&& void *&&&&&&& int n = 0;&&&&&&& int r = 0;&&&&&&&&&&&&&& u_long pages, max_pages, max_&&&&&&& pages = sysconf(_SC_AVPHYS_PAGES);
&&&&&&& max_pages = ULONG_MAX / sysconf(_SC_PAGE_SIZE);&&&&&&& if (pages > max_pages)&&&&&&&&&&&&&&& pages = max_&&&&&&& max_bytes = pages * sysconf(_SC_PAGE_SIZE);
&&&&&&& r = getrlimit (RLIMIT_AS,&rl);
&&&&&&& printf("crrent hard limit is %ld MB\n",&&&&&&&&&&&&&&& (u_long) rl.rlim_max/0x100000);
&&&&&&& rl.rlim_cur = max_&&&&&&& r = setrlimit (RLIMIT_AS, &rl);&&&&&&& if (r){&&&&&&&&&&&&&&& perror("setrlimit");&&&&&&& }
&&&&&&& printf("limit set to %ld MB\n", max_bytes / 0x100000);
&&&&&&& while(1){&&&&&&&&&&&&&&& ptr = malloc(0x100000);
&&&&&&&&&&&&&&& if (ptr == NULL){&&&&&&&&&&&&&&&&&&&&&&& perror("malloc");&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&& memset(ptr, 1, 0x100000);&&&&&&&&&&&&&&& printf("malloced %d MB\n", ++n);&&&&&&& }&&&&&&& printf("paused\n");&&&&&&& raise(SIGSTOP);&&&&&&& return 0;}
先查看一下当前内存利用情况,当前空闲内存为296MB.[root@test1 ~]# free -m &&&&&&&&&&&& total&&&&&& used&&&&&& free&&&& shared&&& buffers&&&& cachedMem:&&&&&&&&&& 503&&&&&&& 206&&&&&&& 296&&&&&&&&& 0&&&&&&&& 28&&&&&&& 141-/+ buffers/cache:&&&&&&&& 36&&&&&&& 466Swap:&&&&&&&& 1027&&&&&&&&& 0&&&&&& 1027
执行callmem2程序[root@test1 tmp]# ./callmem2 crrent hard limit is 4095 MBlimit set to 296 MBmalloced 1 MBmalloced 2 MBmalloced 3 MBmalloced 4 MBmalloced 5 MB......malloced 294 MBmalloc: Cannot allocate memorypaused
[1]+& Stopped&&&&&&&&&&&&&&&& ./callmem2crrent hard limit is 4095 MB当前系统的内存限额为4095MB,也就是4GB的虚拟内存限制.limit set to 296 MB而进程最多也只能用到296MB,最后通过malloc分配到了294MB,还有2MB给了系统库.
再看一下当前的内存:[root@test1 ~]# free -m &&&&&&&&&&&& total&&&&&& used&&&&&& free&&&& shared&&& buffers&&&& cachedMem:&&&&&&&&&& 503&&&&&&& 497&&&&&&&&& 5&&&&&&&&& 0&&&&&&&& 28&&&&&&& 137-/+ buffers/cache:&&&&&&& 331&&&&&&& 171Swap:&&&&&&&& 1027&&&&&&&&& 0&&&&&& 1027
这里为什么还剩下5MB的内存呢,其实它把内存都给了callmem2(剩下的零头没法再给了).它是将cached中的4MB内存释放给了系统.
那么在这种情况下,别的进程还能分配到内存吗?
答案是可以的,但最多只能是分配5MB左右.比如上面free的内存有5MB,进程启动的时候会分配1MB-2MB的内存给系统库.剩下的它会尽可能的占用.再次执行callmem2,进程只分配到了4MB.[root@test1 tmp]# ./callmem2 crrent hard limit is 4095 MBlimit set to 6 MBmalloced 1 MBmalloced 2 MBmalloced 3 MBmalloced 4 MBmalloc: Cannot allocate memorypaused
[2]+& Stopped&&&&&&&&&&&&&&&& ./callmem2
用pmap查看映射的地址,最多用了5728KB.[root@test1 tmp]# jobs -x pmap %22739:&& ./callmem2&& 1244K r-x--& /lib/libc-2.5.so&&&&& 8K r-x--& /lib/libc-2.5.so&&&&& 4K rwx--& /lib/libc-2.5.so&&&& 12K rwx--&&& [ anon ]00b51000&&& 100K r-x--& /lib/ld-2.5.so00b6a000&&&&& 4K r-x--& /lib/ld-2.5.so00b6b000&&&&& 4K rwx--& /lib/ld-2.5.so00ba3000&&&&& 4K r-x--&&& [ anon ]&&&&& 4K r-x--& /tmp/callmem2&&&&& 4K rw---& /tmp/callmem2&&& 132K rw---&&& [ anon ]b7bd8000&& 4116K rw---&&& [ anon ]b7ff0000&&&&& 8K rw---&&& [ anon ]bf938000&&&& 84K rw---&&& [ stack ]&total&&&& 5728K&再次查看内存的利用情况,free还是5MB,这回cached释放了3MB,buffers释放了1MB[root@test1 ~]# free -m &&&&&&&&&&&& total&&&&&& used&&&&&& free&&&& shared&&& buffers&&&& cachedMem:&&&&&&&&&& 503&&&&&&& 497&&&&&&&&& 5&&&&&&&&& 0&&&&&&&& 27&&&&&&& 134-/+ buffers/cache:&&&&&&& 335&&&&&&& 167Swap:&&&&&&&& 1027&&&&&&&&& 0&&&&&& 1027
4)内存限制的总结:
4.1)三种方法都可以防止OOM的发生.4.2)overcommit的方法,只有超级用户都能使用,设成2后,之后所有用户的进程都不能消耗超过实际内存的地址空间,也就收不到OOM信息了.但这种方式并不可控.4.3)ulimit的方法,所有用户都能使用,设定后,当前shell生效,有硬限制和软限制两种方式,这种方式可以控制进程最多占用的内存.4.4)setrlimit的方法,所有用户都能使用,设定后,当前进程有效.有硬限制和软限制两种方式,这种方式也可以控制进程最多占用的内存.4.5)setrlimit一般和sysconf一起联用,但sysconf得到的页面数量只是一个模糊的数,在一个繁忙的系统里,这个值是不定的.4.6)最后说一点,sysconf(_SC_PAGE_SIZE)得到的值是一个可用物理内存的值,而不包括swap.4.6)如果用ulimit设定当前shell下启用的进程最多可用10MB,即使sysconf(_SC_PAGE_SIZE);得到的值是大于10MB,我们也只能用到10MB.例如下面的试验:
[root@test1 tmp]# ulimit -d 10240 -m 10240 -v 10240
[root@test1 tmp]# ./callmem2 crrent hard limit is 10 MBsetrlimit: Invalid argumentlimit set to 328 MBmalloced 1 MBmalloced 2 MBmalloced 3 MBmalloced 4 MBmalloced 5 MBmalloced 6 MBmalloced 7 MBmalloc: Cannot allocate memorypaused
[1]+& Stopped&&&&&&&&&&&&&&&& ./callmem2[root@test1 tmp]# jobs -x pmap %12514:&& ./callmem2&&&&& 4K r-x--&&& [ anon ]00b51000&&& 100K r-x--& /lib/ld-2.5.so00b6a000&&&&& 4K r-x--& /lib/ld-2.5.so00b6b000&&&&& 4K rwx--& /lib/ld-2.5.so00b6e000&& 1244K r-x--& /lib/libc-2.5.so00ca5000&&&&& 8K r-x--& /lib/libc-2.5.so00ca7000&&&&& 4K rwx--& /lib/libc-2.5.so00ca8000&&&& 12K rwx--&&& [ anon ]&&&&& 4K r-x--& /tmp/callmem2&&&&& 4K rw---& /tmp/callmem2b7729000&& 8224K rw---&&& [ anon ]b7f44000&&&&& 8K rw---&&& [ anon ]bfd46000&&&& 84K rw---&&& [ stack ]&total&&&& 9704K
阅读(5900) | 评论(0) | 转发(1) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。

我要回帖

更多关于 物理内存占用过高 的文章

 

随机推荐