虚拟存储子系统调整

                                                  虚拟存储子系统调整        


虚拟空间存储方式

在linux 中是通过页面为单位的虚拟存储方式进行的。采用虚拟存储的方式,不需要连续的物理内存。现在大部分的处理器都具备用于虚拟存储的处理器嵌入式TLB,旁路转换缓冲区,或称页表缓冲区。和处理不存在的页面访问的结构。

其具有以下几种特点:

1.程序使用的页面是在应用程序最初访问时由内核分配的。

2.如果分配的页面是程序文本,有初始值的数据,等等。则在页面分配的同时从对应的文件读取数据,页面通过这些初始化。

3.对于不存在拥有初始值的数据区域,则只进行页面分配处理。

应用程序通过malloc( ) 分配空间的时候,不会立即向该区域分配实际的页面。而是在必要的时候,仅仅分配需要用到的页面。

用虚拟存储方式延迟内存分配,就不需要向为使用的空间分配内存。

分配给进程的虚拟空间大小与本质上安装的物理量无关。但是从系统的稳定性来看,分配的虚拟空间大小应该保证达到物理内存的量。

但是由于需要分配页面,因此程序启动时不能提前得知该应用程序最终使用的最大页面数,这是虚拟存储方式的缺点。进程在逻辑上的虚拟内存空间与实际分配给的空间的实际内存空间已经不再有直接的关系了。最大使用内存量会根据环境(处理的数据等)变化而变化。

ps:

应用程序使用的内存量对系统的稳定性有很大的影响,因此不能无限度地使用内存。

虚拟空间超额使用量的调整。

虚拟地址空间其实并不是实际使用了这么大的实际内存,所以个人觉得从系统的稳定性来看,分配的虚拟空间大小应该保证达到物理内存的量。其实虚拟地址空间开的太大也不好,因为很多没有落实的虚拟地址空间,有可能在实际运行的时候,爆发式请求,然后系统就挂了。其实什么东西多了都不好,做人亦是如此。

当然Linux中也规定了“允许超过物理内存量分配多少虚拟空间”的参数:

在@/proc/sys/vm/overcommit_memory

    @/proc/sys/vm/overcommit_ratio

其中overcommit_memory 是控制虚拟空间的策略的参数,可以设置三种值,这三种都是宏定义

OVERCOMMIT_GUESS:

这个宏是默认值(0);指定这个参数时,预测将空闲内存,页面缓存量,空闲交换区量,可回收slab量等回收的页面数,虚拟空间要求分配量比这个数少时,分配成功。在这种情况下,可分配的虚拟空间大小基本就是物理内存的大小和交换区大小的合计值,物理空间2G,交换2G,当前消耗1G时,还可以分配约3G 内存。

OVERCOMMIT_ALWAYS(1):

在这种情况下,任何时候都是可以分配成功的,即使是较大的虚拟地址空间都是可以的。

OVERCOMMIT_NEVER(2):

这是严格管理可分配虚拟地址空间的。

计算公式:

(  所有物理内存量 + 总交换区  ) * 比例  =   可分配的虚拟地指空间总量。

ramzswap:

ramzswap 是将一部分内存空间作为交换设备使用的基于RAM 的设备。对要换出的页面进行压缩后,不是写入磁盘,而是写入内存。可以使用的内存仅为完成压缩的部分。压缩处理使用的是LZO 算法。这个算法不再今天的讨论范围内(贴上一个百度的介绍吧:LZO 是致力于解压速度的一种数据压缩算法,LZO 是 Lempel-Ziv-Oberhumer 的缩写。这个算法是无损算法,参考实现程序是线程安全的。 实现它的一个自由软件工具是lzop。最初的库是用 ANSI C 编写、并且遵从 GNU公共通用许可证发布的。现在 LZO 有用于 Perl、Python 以及 Java 的各种版本。代码版权的所有者是 Markus F. X. J. Oberhumer。)

 使用这种设备后,机器的运转速率比换出一般磁盘设备时更高,这是因为内存的I/O较快,且经过压缩后I/O 变小了。这种优化非常关键:像在一些嵌入式设备上,一旦内存被占满,启动了内存回收机制后,会直接导致处理器性能在这段时间内快速下降,或者抑制OOM killer 的运行。

        这个工具的使用暂时不展开介绍,会在后续的系统优化专题中阐述。其实一个在工具而已,百度就OK 。

总的来说:

可以通过压缩页面数据收益,即使时多一些处理的开销也总好过内存耗尽。

OOM Killer:

在linux 中这是处理内存爆满,保护操作系统不挂的最后手段,其实也很简单,杀死那个占内存的进程就OK了。在耗尽内存或交换区后,向进程发送信号,强制终止该进程.

首先来看下例子:

<span style="font-size:18px;">#include<stdio.h>
#include<malloc.h>
#include<unistd.h>
int main()
{
    while(1){
      int *p;
      p = (int *)malloc(sizeof(int)*10000000);
      usleep(20);
    }
    
}</span>


这是一个非常简单的可以消耗内存的程序,当这个程序一直运行最后,它就会被杀死。

使用demsg 查看可以发现是OOM Killer 杀死了它。




内核日志指出它是因为内存超出才被杀死了.

其实并不一定只有超出内存之后才会杀死它,长时间占用内核的进程也有可能被杀死。其实这是有九项规定的:

1.首先计算进程的虚拟内存大小,单位是1KB 为 1 分,消耗1G内存的进程得分约1 000 000 分

2.如果进程正在调用swapoff 系统调用,则分数被设置成最大值,这个进程想禁用交换分区,这是变相消耗内存,所以格杀无论。

3.如果是父进程,就计算子进程占内存的一半

4.根据CPU 的分配来判断,这里认为长时间,高频率占用CPU 的进程是重要的进程,需要保持低分。

公式:

得分/cpu使用时间的平方根

得分/启动时间的平方根

5.对于人为ie设置nice的进程,得分会变高,计算方法:直接翻倍。

6.特权进程普遍重要,得分为四分之一。

7.使用了capset( )的函数的进程,得分为四分之一,硬件操作为重要进程。

8. 关于Cgroup,如果进程只允许与促使OOM Killer 运行的进程锁允许的内存节点完全不同的内存节点,则得分为八分之一。

9.根据oom_obj 的值调整得分。


最终根据这些分数,得分最高的就被杀死了。

基本这些就是虚拟内存子系统一些可以说是优化的点了。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值