首页 Linux大内存应用进程被杀-读写4GB文件记录
文章
取消

Linux大内存应用进程被杀-读写4GB文件记录

前言

最近搞MPI实验,与其说在搞并行计算,还不如说在搞操作系统…入门最大的问题还不是MPI编程,就是搞系统优化就够呛的。无论是Windows还是Linux,对于吃超大内存的应用都不是十分友好,以往没有什么超大规模数据处理、大内存应用的处理经验。故此记录一般。

问题

简单描述一下简单的应用场景:需要生成一大批随机数据(float类型,大小在0-1之间),最大大小位4GB。然后从文件中读取数据,使用qsort对数据进行排序。

问题:4GB float数据,需要至少16G的内存空间,差不多超出了物理RAM的大小。强行执行的话,会在运行一段时间后,程序被杀掉。xxx(进程ID) is killed。

解决

在开始聊解决方案之前,先来过一下Linux操作系统的一些配置请求命令。

编程

对于程序语言中的高级接口来说,一般不需要考虑调用接口的数据大小。数据读写由接口内部缓冲机制来保证。比如C语言中,fwrite和fread,一般来说可以直接相信它们能够正确调用(而无论数据的大小)。如果是特别大的文件,在Linux中启用64位文件偏移(默认32位,即long类型长度),则可以添加CFLAGSS,-D_FILE_OFFSET_BITS=64

示例:

1
gcc make_data.c -o make-data -D_FILE_OFFSET_BITS=64

另外,如果从高层考虑数据大小(或者程序空间的大小,堆空间、栈空间等),可以考虑把数据切块:

    // handle big data
    unsigned long handled_number = 0;
    unsigned long number_of_Gb = 1073741824;
    while (N > number_of_Gb)
    {
        fwrite(data + handled_number, sizeof(float), number_of_Gb, file);
        handled_number += number_of_Gb;
        N -= number_of_Gb;
    }
    fwrite(data + handled_number, sizeof(float), N, file);

但是对一般排序算法,数据需要一起加载,则无法使用。

系统配置

要使上述的程序顺利完成,在最恶劣情况需要将4GB数据、float类型,读取到内存中,对于程序来说,4G*4,至少需要16GB的逻辑内存(不一定需要这么强的物理资源)。我们的物理资源,即内存条可能只有8G、或者16G,在虚拟机中不一定能分配到这么大的资源。这个时候就需要虚拟内存的技术。只要保证虚拟内存+RAM大于程序需要的逻辑内存即可。反过来,如果虚拟内存+RAM小于程序需要的逻辑内存,那么程序必然会访问超出逻辑地址空间的资源,导致程序被杀掉。所以程序不能跑起来一定要检查内存是不是被吃光了。

下面是Linux上设置虚拟内存的方式(在Linux中需要做的是设置交换文件,即swap)

  1. 执行“sudo swapon -s”命令,查看是否已经存在swap file

    如果第一步存在swapfile则需要先禁用

sudo swapoff /swapfile
  1. 修改swap 空间的大小为8G
1
sudo dd if=/dev/zero of=/swapfile bs=1M count=8192
  1. 设置文件为“swap file”类型
sudo mkswap /swapfile
  1. 启用swapfile
sudo swapon /swapfile

链接:https://www.jianshu.com/p/e656bead51ee

注意(坑):以上操作必须一起完成!!否则在swapoff了原本的swapfile之后会导致无法开机。因为系统没办法挂载原本的swapfile。如果中间没完成,记得重新把/swapfile挂载回去!

然后如果是使用WSL,配置方式:

添加文件.wslconfig,文件路径为 C:\Users\<UserName>\.wslconfig.文件内容:

1
2
3
4
5
# Settings apply across all Linux distros running on WSL 2
[wsl2]

# Sets amount of swap storage space to 8GB, default is 25% of available RAM
swap=40GB

注意如果是动态修改不能更改swap位置,否则不能生效(这里跟上面linux同理,不能更改系统原本的swapfile文件,否则会导致系统损坏,或者不起效)。要更改swap位置,必须重装或新安装时就指定。

更多设置和解释:

WSL高级设置配置-官网

Understanding your WSL2 RAM and swap - Changing the default 50%-25%

配置完成后,实测4GB数据能够正常运行,4GB float数据排序,需要时间:1.310827E+03(排序时间)。

意外

在VMWare虚拟机配置swap过程中,踩了一个坑,就是上面提到swapoff之后没完成整个过程就关机了,导致无法启动。

整个过程主要是,在分配swap10GB空间时,磁盘刚好满了。然后就想关机扩展磁盘空间。然后扩展磁盘空间又必须把快照删了…然后就启动不了(原因在上面提了)。寄。

咋办呢。解决:开启时,查看下方一行提示,按ESC进入高级选项,选择ubuntu recovery mode,选择root,进入命令行。把原本占满磁盘空间的swapfile改小一点,重新挂载上swapfile,重启即可(具体命令参见上面)。

扩展磁盘的方式:VMWare,点击磁盘大小,将最大大小改大,启动后使用gparted挂载空间(这是图形化方式,不能用图形化用自带的fdisk)

本文由作者按照 CC BY 4.0 进行授权

windows 反流氓

VMWare虚拟机网络探讨-桥接、NAT、仅主机配置