linux 如何释放手机虚拟内存存

Author:Echo Chen(陈斌)
Date:Jan.27th, 2015
最近游戏已上线运营,进行服务器内存优化,发现一个非常奇妙的问题,我们的认证服务器(AuthServer)负责跟第三方渠道SDK打交道(登陆和充值),由于采用了curl阻塞的方式,所以这里开了128个线程,奇怪的是每次刚启动的时候占用的虚拟内存在2.3G,然后每次处理消息就增加64M,增加到4.4G就不再增加了,由于我们采用预分配的方式,在线程内部根本没有大块分内存,那么这些内存到底是从哪来的呢?让人百思不得其解。
一开始首先排除掉内存泄露,不可能每次都泄露64M内存这么巧合,为了证明我的观点,首先,我使用了valgrind。
1: valgrind --leak-check=full --track-fds=yes --log-file=./AuthServer.vlog &
然后启动,跑至内存不再增加,果然valgrind显示没有任何内存泄露。反复试验了很多次,结果都是这样。
在多次使用valgrind无果以后,我开始怀疑程序内部是不是用到mmap之类的调用,于是使用strace对mmap,brk等系统函数的检测:
1: strace -f -e"brk,mmap,munmap" -p $(pidof AuthServer)
其结果如下:
1: [pid 19343] mmap(NULL, , PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f53c8ca9000
2: [pid 19343] munmap(0x7f53c8ca28) = 0
3: [pid 19343] munmap(0x7f53d275136) = 0
4: [pid 19343] mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f53d04a8000
5: Process 19495 attached
我检查了一下trace文件也没有发现大量内存mmap动作,即便是brk动作引起的内存增长也不大。于是感觉人生都没有方向了,然后怀疑是不是文件缓存把虚拟内存占掉了,注释掉了代码中所有读写日志的代码,虚拟内存依然增加,排除了这个可能。
2.灵光一现
后来,我开始减少thread的数量开始测试,在测试的时候偶然发现一个很奇怪的现象。那就是如果进程创建了一个线程并且在该线程内分配一个很小的内存1k,整个进程虚拟内存立马增加64M,然后再分配,内存就不增加了。测试代码如下:
1: #include &iostream&
2: #include &stdio.h&
3: #include &stdlib.h&
4: #include &unistd.h&
7: volatile&bool start = 0;
10: void* thread_run( void* )
13:&&& while(1)
15:&&&&&&&& if(start)
16:&&&&&&&& {
17:&&&&&&&&&&&&&&&& cout && "Thread malloc" &&
18:&&&&&&&&&&&&&&&& char *buf = new&char[1024];
19:&&&&&&&&&&&&&&&& start = 0;
20:&&&&&&&& }
21:&&&&&&&& sleep(1);
25: int main()
27:&&&& pthread_
29:&&&& getchar();
30:&&&& getchar();
31:&&&& pthread_create(&th, 0, thread_run, 0);
33:&&&& while((getchar()))
35:&&&&&&&& start& = 1;
39:&&&& return 0;
其运行结果如下图,刚开始时,进程占用虚拟内存14M,输入0,创建子线程,进程内存达到23M,这增加的10M是线程堆栈的大小(查看和设置线程堆栈大小可用ulimit &s),第一次输入1,程序分配1k内存,整个进程增加64M虚拟内存,之后再输入2,3,各再次分配1k,内存均不再变化。
这个结果让我欣喜若狂,由于以前学习过谷歌的Tcmalloc,其中每个线程都有自己的缓冲区来解决多线程内存分配的竞争,估计新版的glibc同样学习了这个技巧,于是查看pmap $(pidof main) 查看内存情况,如下:
请注意65404这一行,种种迹象表明,这个再加上它上面那一行(在这里是132)就是增加的那个64M)。后来增加thread的数量,就会有新增thread数量相应的65404的内存块。
3.刨根问底
经过一番google和代码查看。终于知道了原来是glibc的malloc在这里捣鬼。glibc 版本大于2.11的都会有这个问题:在redhat 的官方文档上:
&& Red Hat Enterprise Linux 6 features version 2.11 of glibc, providing many features and enhancements, including... An enhanced dynamic memory allocation (malloc) behaviour enabling higher scalability across many sockets and cores.This is achieved by assigning threads their own memory pools and by avoiding locking in some situations. The amount of additional memory used for the memory pools (if any) can be controlled using the environment variables MALLOC_ARENA_TEST and MALLOC_ARENA_MAX. MALLOC_ARENA_TEST specifies that a test for the number of cores is performed once the number of memory pools reaches this value. MALLOC_ARENA_MAX sets the maximum number of memory pools used, regardless of the number of cores.
The developer, Ulrich Drepper, has a much deeper explanation on his blog:
&&& Before, malloc tried to emulate a per-core memory pool. Every time when contention for all existing memory pools was detected a new pool is created. Threads stay with the last used pool if possible... This never worked 100% because a thread can be descheduled while executing a malloc call. When some other thread tries to use the memory pool used in the call it would detect contention. A second problem is that if multiple threads on multiple core/sockets happily use malloc without contention memory from the same pool is used by different cores/on different sockets. This can lead to false sharing and definitely additional cross traffic because of the meta information updates. There are more potential problems not worth going into here in detail.
&&&The changes which are in glibc now create per-thread memory pools.&This can eliminate false sharing in most cases. The meta data is usually accessed only in one thread (which hopefully doesn&t get migrated off its assigned core). To prevent the memory handling from blowing up the address space use too much the number of memory pools is capped. By default we create up to two memory pools per core on 32-bit machines and up to eight memory per core on 64-bit machines. The code delays testing for the number of cores (which is not cheap, we have to read /proc/stat) until there are already two or eight memory pools allocated, respectively.
While these changes might increase the number of memory pools which are created (and thus increase the address space they use) the number can be controlled. Because using the old mechanism there could be a new pool being created whenever there are collisions the total number could in theory be higher. Unlikely but true, so the new mechanism is more predictable.
... Memory use is not that much of a premium anymore and most of the memory pool doesn&t actually require memory until it is used, only address space... We have done internally some measurements of the effects of the new implementation and they can be quite dramatic.
&& New versions of glibc present in RHEL6 include a new&arena allocator design. In several clusters we've seen this new allocator cause huge amounts of virtual memory to be used, since when multiple threads perform allocations, they each get their own memory arena.&On a 64-bit system, these arenas are 64M mappings, and the maximum number of arenas is 8 times the number of cores. We've observed a DN process using 14GB of vmem for only 300M of resident set. This causes all kinds of nasty issues for obvious reasons.
Setting MALLOC_ARENA_MAX to a low number will restrict the number of memory arenas and bound the virtual memory, with no noticeable downside in performance - we've been recommending MALLOC_ARENA_MAX=4. We should set this in-env.sh to avoid this issue as RHEL6 becomes more and more common.
总结一下,glibc为了分配内存的性能的问题,使用了很多叫做arena的memory pool,缺省配置在64bit下面是每一个arena为64M,一个进程可以最多有 cores * 8个arena。假设你的机器是4核的,那么最多可以有4 * 8 = 32个arena,也就是使用32 * 64 = 2048M内存。 当然你也可以通过设置环境变量来改变arena的数量.例如export MALLOC_ARENA_MAX=1hadoop推荐把这个值设置为4。当然了,既然是多核的机器,而arena的引进是为了解决多线程内存分配竞争的问题,那么设置为cpu核的数量估计也是一个不错的选择。设置这个值以后最好能对你的程序做一下压力测试,用以看看改变arena的数量是否会对程序的性能有影响。
mallopt(M_ARENA_MAX, xxx)如果你打算在程序代码中来设置这个东西,那么可以调用mallopt(M_ARENA_MAX, xxx)来实现,由于我们AuthServer采用了预分配的方式,在各个线程内并没有分配内存,所以不需要这种优化,在初始化的时候采用mallopt(M_ARENA_MAX, 1)将其关掉,设置为0,表示系统按CPU进行自动设置。
4.意外发现
想到tcmalloc小对象才从线程自己的内存池分配,大内存仍然从中央分配区分配,不知道glibc是如何设计的,于是将上面程序中线程每次分配的内存从1k调整为1M,果然不出所料,再分配完64M后,仍然每次都会增加1M,由此可见,新版 glibc完全借鉴了tcmalloc的思想。
忙了几天的问题终于解决了,心情大好,通过今天的问题让我知道,作为一个服务器程序员,如果不懂编译器和内核,是完全不合格的,以后要加强这方面的学习。
Echo Chen:
阅读(...) 评论()虚拟内存怎么设置最好linux_百度知道
虚拟内存怎么设置最好linux
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
佛陀娃娃高朝晖
来自电子数码类芝麻团
佛陀娃娃高朝晖
采纳数:14350
获赞数:10191
参与团队:
linux的虚拟内存优化_百度经验:
保准你喜欢
保准你喜欢
采纳数:472
获赞数:26119
在终端中运行 fdisk -l 查看哪个分区有空,然后运行 sudo mkswap /dev/sda 添加交换分区, sudo swapon /dev/sda启用分区, sudo /dev/sda swap swap ...
本回答被提问者和网友采纳
为你推荐:
其他类似问题
您可能关注的内容
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。Linux 虚拟内存管理
最近在做 MySQL 版本升级时( 5.1-&5.5 ) , 发现了 mysqld 疑似“内存泄露”现象,但通过 valgrind 等工具检测后,并没发现类似的问题。因此,需要深入学习 Linux 的虚拟内存管理方面的内容来解释这个现象。
Linux 的虚拟内存管理有几个关键概念:
每个进程有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址
虚拟地址可通过每个进程上页表与物理地址进行映射,获得真正物理地址
如果虚拟地址对应物理地址不在物理内存中,则产生缺页中断,真正分配物理地址,同时更新进程的页表;如果此时物理内存已耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中。
基于以上认识,这篇文章通过本人以前对虚拟内存管理的疑惑由浅入深整理了以下十个问题,并通过例子和系统命令尝试进行解答。
Linux 虚拟地址空间如何分布? 32 位和 64 位有何不同?
malloc 是如何分配内存的?
malloc 分配多大的内存,就占用多大的物理内存空间吗?
如何查看进程虚拟地址空间的使用情况?
free 的内存真的释放了吗(还给 OS ) ?
程序代码中 malloc 的内存都有相应的 free ,就不会出现内存泄露了吗?
既然堆内内存不能直接释放,为什么不全部使用 mmap 来分配?
如何查看进程的缺页中断信息?
如何查看堆内内存的碎片情况?
除了 glibc 的 malloc/free ,还有其他第三方实现吗?
一.Linux 虚拟地址空间如何分布? 32 位和 64 位有何不同?
Linux 使用虚拟地址空间,大大增加了进程的寻址空间,由低地址到高地址分别为:
只读段:该部分空间只能读,不可写,包括代码段、 rodata 段( C 常量字符串和 #define 定义的常量)
数据段:保存全局变量、静态变量的空间
堆 :就是平时所说的动态内存, malloc/new 大部分都来源于此。其中堆顶的位置可通过函数 brk 和 sbrk 进行动态调整。
文件映射区域 :如动态库、共享内存等映射物理空间的内存,一般是 mmap 函数所分配的虚拟地址空间。
栈:用于维护函数调用的上下文空间,一般为 8M ,可通过 ulimit –s 查看。
内核虚拟空间:用户代码不可见的内存区域,由内核管理。
下图是 32 位系统典型的虚拟地址空间分布(来自《深入理解计算机系统》)。
32 位系统有 4G 的地址空间,其中0xxbfffffff 是用户空间, 0xcxffffffff 是内核空间,包括内核代码和数据、与进程相关的数据结构(如页表、内核栈)等。另外, %esp 执行栈顶,往低地址方向变化; brk/sbrk 函数控制堆顶往高地址方向变化。
可通过以下代码验证进程的地址空间分布,其中 sbrk(0) 函数用于返回栈顶指针。
#include &stdlib.h&
#include &stdio.h&
#include &string.h&
#include &unistd.h&
int global_num = 0;
char global_str_arr [65536] = {'a'};
int main(int argc, char** argv)
char* heap_var = NULL;
int local_var = 0;
printf("Address of function main 0x%lx\n", main);
printf("Address of global_num 0x%lx\n", &global_num);
printf("Address of global_str_arr 0x%lx ~ 0x%lx\n", &global_str_arr[0], &global_str_arr[65535]);
printf("Top of stack is 0x%lx\n", &local_var);
printf("Top of heap is 0x%lx\n", sbrk(0));
heap_var = malloc(sizeof(char) * 127 * 1024);
printf("Address of heap_var is 0x%lx\n", heap_var);
printf("Top of heap after malloc is 0x%lx\n", sbrk(0));
free(heap_var);
heap_var = NULL;
printf("Top of heap after free is 0x%lx\n", sbrk(0));
32 位系统的结果如下,与上图的划分保持一致,并且栈顶指针在 mallloc 和 free 一个 127K 的存储空间时都发生了变化(增大和缩小)。
Address of function main 0x8048474
Address of global_num 0x8059904
Address of global_str_arr 0x8049900 ~ 0x80598ff
Top of stack is 0xbfd0886c
Top of heap is 0x805a000
Address of heap_var is 0x805a008
Top of heap after malloc is 0x809a000
Top of heap after free is 0x807b000
但是, 64 位系统结果怎样呢? 64 位系统是否拥有 2^64 的地址空间吗?
64 位系统运行结果如下:
Address of function main 0x400594
Address of global_num 0x610b90
Address of global_str_arr 0x600b80 ~ 0x610b7f
Top of stack is 0x7fff2e9e4994
Top of heap is 0x8f5000
Address of heap_var is 0x8f5010
Top of heap after malloc is 0x935000
Top of heap after free is 0x916000
从结果知,与上图的分布并不一致。而事实上, 64 位系统的虚拟地址空间划分发生了改变:
地址空间大小不是 2^32 ,也不是 2^64 ,而一般是 2^48 。因为并不需要 2^64 这么大的寻址空间,过大空间只会导致资源的浪费。 64 位 Linux 一般使用 48 位来表示虚拟地址空间, 40 位表示物理地址,这可通过 /proc/cpuinfo 来查看
address sizes : 40 bits physical, 48 bits virtual
其中, 0x07fffffffffff表示用户空间,0xFFFF~ 0xFFFFFFFFFFFFFFFF表示内核空间,共提供 256TB(2^48) 的寻址空间。这两个区间的特点是,第 47 位与 48~63 位相同,若这些位为 0 表示用户空间,否则表示内核空间。
用户空间由低地址到高地址仍然是只读段、数据段、堆、文件映射区域和栈
二.malloc 是如何分配内存的?
malloc 是 glibc 中内存分配函数,也是最常用的动态内存分配函数,其内存必须通过 free 进行释放,否则导致内存泄露。
关于 malloc 获得虚存空间的实现,与 glibc 的版本有关,但大体逻辑是:
若分配内存小于 128k ,调用 sbrk() ,将堆顶指针向高地址移动,获得新的虚存空间。
若分配内存大于 128k ,调用 mmap() ,在文件映射区域中分配匿名虚存空间。
这里讨论的是简单情况,如果涉及并发可能会复杂一些,不过先不讨论。
其中 sbrk 就是修改栈顶指针位置,而 mmap 可用于生成文件的映射以及匿名页面的内存,这里指的是匿名页面。
而这个 128k ,是 glibc 的默认配置,可通过函数 mallopt 来设置,可通过以下例子说明。
#include &stdlib.h&
#include &stdio.h&
#include &string.h&
#include &unistd.h&
#include &sys/mman.h&
#include &malloc.h&
void print_info(
char* var_name,
char* var_ptr,
size_t size_in_kb
printf("Address of %s(%luk) 0x%lx, now heap top is 0x%lx\n",
var_name, size_in_kb, var_ptr, sbrk(0));
int main(int argc, char** argv)
char *heap_var1, *heap_var2, *heap_var3 ;
char *mmap_var1, *mmap_var2, *mmap_var3 ;
char *maybe_mmap_
printf("Orginal heap top is 0x%lx\n", sbrk(0));
heap_var1 = malloc(32*1024);
print_info("heap_var1", heap_var1, 32);
heap_var2 = malloc(64*1024);
print_info("heap_var2", heap_var2, 64);
heap_var3 = malloc(127*1024);
print_info("heap_var3", heap_var3, 127);
printf("\n");
maybe_mmap_var = malloc(128*1024);
print_info("maybe_mmap_var", maybe_mmap_var, 128);
mmap_var1 = malloc(128*1024);
print_info("mmap_var1", mmap_var1, 128);
// set M_MMAP_THRESHOLD to 64k
mallopt(M_MMAP_THRESHOLD, 64*1024);
printf("set M_MMAP_THRESHOLD to 64k\n");
mmap_var2 = malloc(64*1024);
print_info("mmap_var2", mmap_var2, 64);
mmap_var3 = malloc(127*1024);
print_info("mmap_var3", mmap_var3, 127);
这个例子很简单,通过 malloc 申请多个不同大小的动态内存,同时通过接口 print_info 打印变量大小和地址等相关信息,其中 sbrk(0) 可返回堆顶指针位置。另外,粗体部分是将 MMAP 分配的临界点由 128k 转为 64k ,再打印变量地址的不同。
下面是 Linux 64 位机器的执行结果(后文所有例子都是通过 64 位机器上的测试结果)。
Orginal heap top is 0x17da000
Address of heap_var1(32k) 0x17da010, now heap top is 0x1803000
Address of heap_var2(64k) 0x17e2020, now heap top is 0x1803000
Address of heap_var3(127k) 0x17f2030, now heap top is 0x1832000
Address of maybe_mmap_var(128k) 0x1811c40, now heap top is 0x1832000
Address of mmap_var1(128k) 0x7f4a0b1f2010, now heap top is 0x1832000
set M_MMAP_THRESHOLD to 64k
Address of mmap_var2(64k) 0x7f4a0b1e1010, now heap top is 0x1832000
Address of mmap_var3(127k) 0x7f4a0b1c1010, now heap top is 0x1832000
三.malloc 分配多大的内存,就占用多大的物理内存空间吗?
我们知道, malloc 分配的的内存是虚拟地址空间,而虚拟地址空间和物理地址空间使用进程页表进行映射,那么分配了空间就是占用物理内存空间了吗?
首先,进程使用多少内存可通过 ps aux 命令 查看,其中关键的两信息(第五、六列)为:
VSZ , virtual memory size ,表示进程总共使用的虚拟地址空间大小,包括进程地址空间的代码段、数据段、堆、文件映射区域、栈、内核空间等所有虚拟地址使用的总和,单位是 K
RSS , resident set size ,表示进程实际使用的物理内存空间, RSS 总小于 VSZ 。
可通过一个例子说明这个问题:
#include &stdlib.h&
#include &stdio.h&
#include &string.h&
#include &unistd.h&
#include &sys/mman.h&
#include &malloc.h&
char ps_cmd[1024];
void print_info(
char* var_name,
char* var_ptr,
size_t size_in_kb
printf("Address of %s(%luk) 0x%lx, now heap top is 0x%lx\n",
var_name, size_in_kb, var_ptr, sbrk(0));
system(ps_cmd);
int main(int argc, char** argv)
char *non_set_var, *set_1k_var, *set_5k_var, *set_7k_
pid = getpid();
sprintf(ps_cmd, "ps aux | grep %lu | grep -v grep", pid);
non_set_var = malloc(32*1024);
print_info("non_set_var", non_set_var, 32);
set_1k_var = malloc(64*1024);
memset(set_1k_var, 0, 1024);
print_info("set_1k_var", set_1k_var, 64);
set_5k_var = malloc(127*1024);
memset(set_5k_var, 0, 5*1024);
print_info("set_5k_var", set_5k_var, 127);
set_7k_var = malloc(64*1024);
memset(set_1k_var, 0, 7*1024);
print_info("set_7k_var", set_7k_var, 64);
该代码扩展了上一个例子print_info能力,处理打印变量信息,同时通过 ps aux 命令获得当前进程的 VSZ 和 RSS 值。并且程序 malloc 一块内存后,会 memset 内存的若干 k 内容。
执行结果为
Address of non_set_var(32k) 0x502010, now heap top is 0x52b000
pts/3 S+ 20:29 0:00 ./test_vsz
Address of set_1k_var(64k) 0x50a020, now heap top is 0x52b000
pts/3 S+ 20:29 0:00 ./test_vsz
Address of set_5k_var(127k) 0x51a030, now heap top is 0x55a000
pts/3 S+ 20:29 0:00 ./test_vsz
Address of set_7k_var(64k) 0x539c40, now heap top is 0x55a000
pts/3 S+ 20:29 0:00 ./test_vsz
由以上结果知:
VSZ 并不是每次 malloc 后都增长,是与上一节说的堆顶没发生变化有关,因为可重用堆顶内剩余的空间,这样的 malloc 是很轻量快速的。
但如果 VSZ 发生变化,基本与分配内存量相当,因为 VSZ 是计算虚拟地址空间总大小。
RSS 的增量很少,是因为 malloc 分配的内存并不就马上分配实际存储空间,只有第一次使用,如第一次 memset 后才会分配。
由于每个物理内存页面大小是 4k ,不管 memset 其中的 1k 还是 5k 、 7k ,实际占用物理内存总是 4k 的倍数。所以 RSS 的增量总是 4k 的倍数。
因此,不是 malloc 后就马上占用实际内存,而是第一次使用时发现虚存对应的物理页面未分配,产生缺页中断,才真正分配物理页面,同时更新进程页面的映射关系。这也是 Linux 虚拟内存管理的核心概念之一。
四. 如何查看进程虚拟地址空间的使用情况?
进程地址空间被分为了代码段、数据段、堆、文件映射区域、栈等区域,那怎么查询这些虚拟地址空间的使用情况呢?
Linux 提供了 pmap 命令来查看这些信息,通常使用 pmap -d $pid (高版本可提供 pmap -x $pid)查询,如下所示:
mysql@ TLOG_590_591:~/vin/test_memory& pmap -d 17867
17867: test_mmap
START SIZE RSS DIRTY PERM OFFSET DEVICE MAPPING
K 4K 0K r-xp :01 /home/mysql/vin/test_memory/test_mmap
K 8K 8K rw-p :01 /home/mysql/vin/test_memory/test_mmap
K 0K 0K rw-p :00 [heap]
K 0K 0K rw-p :00 [anon]
2b 108K 92K 0K r-xp :01 /lib64/ld-2.4.so
2b 8K 8K 8K rw-p 2b 00:00 [anon]
2b 4K 4K 4K rw-p 2b 00:00 [anon]
2b 8K 8K 8K rw-p :01 /lib64/ld-2.4.so
2b K 0K r-xp :01 /lib64/libc-2.4.so
2b K ---p :01 /lib64/libc-2.4.so
2b 12K 12K 12K r--p :01 /lib64/libc-2.4.so
2b3K 8K 8K rw-p :01 /lib64/libc-2.4.so
2b348K 36K 36K rw-p 2b3:00 [anon]
7fff81afe000 84K 12K 12K rw-p 7fff81afe000 00:00 [stack]
ffffffffff2K 0K 0K ---p :00 [vdso]
Total: 1K 96K
从这个结果可以看到进程虚拟地址空间的使用情况,包括起始地址、大小、实际使用内存、脏页大小、权限、偏移、设备和映射文件等。 pmap 命令就是基于下面两文件内容进行解析的:
/proc/$pid/maps
/proc/$pid/smaps
并且对于上述每个内存块区间,内核会使用一个 vm_area_struct 结构来维护,同时通过页面建立与物理内存的映射关系,如下图所示。
责任编辑:
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
今日搜狐热点linux系统添加swap虚拟内存与删除配置
& 发布时间: 16:48:53 & 作者:佚名 &
Swap分区,即交换区,Swap空间的作用可简单描述为当系统的物理内存不够用的时候,就需要将物理内存中的一部分空间释放出来,以供当前运行的程序使用,这篇文章主要介绍了linux系统添加swap虚拟内存与删除配置的方法,需要的朋友可以参考下
1.swap概述Swap分区,即交换区,Swap空间的作用可简单描述为:当系统的物理内存不够用的时候,就需要将物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap空间中,等到那些程序要运行时,再从Swap中恢复保存的数据到内存中。这样,系统总是在物理内存不够时,才进行Swap交换。 其实,Swap的调整对Linux服务器,特别是Web服务器的性能至关重要。通过调整Swap,有时可以越过系统性能瓶颈,节省系统升级费用。
2.创建swap由于在安装Centos 6.0 操作系统时候忘记创建创建swap分区,导致使用zabbix对该服务器监控时出现报警。这时才发现,没有创建swap分区。所以需要创建一个swap分区,操作如下:
首先,用拥有ROOT权限的用户通过SSH远程登入或者本地终端登入到系统,进行创建swap分区
dd if=/dev/zero of=/swap/swap bs=1024 count=1024000
if //输入of //输出bs //块儿大小count //总大小创建Linux交换文件mkswap /swap/swap立即激活/swap/swap交换文件swapon /swap/swap查看是否生效[root@webserver ~]# free -mtotal used free shared buffers cachedMem: 7 0 8 35-/+ buffers/cache: 96 1911Swap: 972 0 972通过以上输出信息可以看出,已经成功创建swap分区。设置成永久生效虽然现在已经生效,但是等下次服务器重启之后。该swap虚拟磁盘会失效,为保证永久生效,需要在/etc/fstab文件添加如下指令集:echo &/swap/swap swap swap defaults 0 0& && /etc/fstab现在为止,swap分区已经完成创建。
2.删除swap分区
有时可能会需要删除swap分区,该如何正确进行删除分区哪?
首先停止swap分区swapoff /swap/swap删除swap分区文件rm -rf /swap/swap删除&/etc/swap&指定文件这样就可以手工添加和删除swap分区。代码如下:sed -i "/'\/swa\/swap swap swap defaults 0 0'//" /etc/fstab
大家感兴趣的内容
12345678910
最近更新的内容

我要回帖

更多关于 虚拟内存有什么坏处 的文章

 

随机推荐