Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 增加虚拟内存而不增加虚拟机大小_Linux_Fortran_Mpi - Fatal编程技术网

Linux 增加虚拟内存而不增加虚拟机大小

Linux 增加虚拟内存而不增加虚拟机大小,linux,fortran,mpi,Linux,Fortran,Mpi,我在谷歌和这个网站上搜索了我的问题,但我仍然不明白解决方案 我有一个MPI程序,它RECV一些数据。程序在大数组中崩溃,错误内存不足,因此我开始考虑 /PRO/SUB/STATION/COD>文件。 在MPI_RECV之前,它是: Name: model.exe VmPeak: 841640 kB VmSize: 841640 kB VmHWM: 15

我在谷歌和这个网站上搜索了我的问题,但我仍然不明白解决方案

我有一个
MPI
程序,它
RECV
一些数据。程序在大数组中崩溃,错误内存不足,因此我开始考虑<代码> /PRO/SUB/STATION/COD>文件。 在MPI_RECV之前,它是:

Name:   model.exe                                                               
VmPeak:   841640 kB
VmSize:   841640 kB
VmHWM:     15100 kB
VmRSS:     15100 kB
VmData:   760692 kB
及之后:

Name:   model.exe                                                            
VmPeak:   841640 kB
VmSize:   841640 kB
VmHWM:    719980 kB
VmRSS:    719980 kB
VmData:   760692 kB
我在Ubuntu上测试它,通过系统监视器我看到内存在增加。但我感到困惑的是,
VmSize
(和
VmPeak
)参数没有变化

问题是——实际内存使用的指标是什么

这是否意味着,真正的指标是
VmRSS
?(并且
VmSize
只分配了内存,但仍然没有使用内存)

(您的问题的可能解决方案是最后一段)

在大多数具有虚拟内存的现代操作系统上,内存分配是一个两阶段的过程。首先,保留进程的一部分虚拟地址空间,并且进程的虚拟内存大小(
VmSize
)相应增加。这将在所谓的流程页面表中创建条目。页面最初与物理内存帧没有关联,即没有实际使用物理内存。每当实际读取或写入此分配部分的某些部分时,就会发生页面错误,操作系统会从物理内存安装(映射)一个空闲页面。这会增加进程的常驻集大小(
VmRSS
)。当一些其他进程需要内存时,操作系统可能会将一些不常使用的页面(不常使用的页面的定义高度依赖于实现)的内容存储到一些持久性存储(大多数情况下是硬盘驱动器,或者通常是交换设备),然后取消映射。此过程会减少RSS,但保持
VmSize
不变。如果以后访问此页面,将再次出现页面错误并将其恢复。虚拟内存大小仅在释放虚拟内存分配时减小。请注意,
VmSize
还计算内存映射文件(即可执行文件及其链接到的所有共享库或其他显式映射文件)和共享内存块

进程中有两种通用的内存类型—静态分配内存和堆内存。静态分配的内存保留所有常量和全局/静态变量。它是数据段的一部分,其大小由
VmData
度量表示。数据段还承载程序堆的一部分,在那里分配动态内存。数据段是连续的,也就是说,它从某个位置开始,向堆栈方向向上增长(堆栈从非常高的地址开始,然后向下增长)。数据段中的堆的问题在于,它由一个特殊的堆分配器管理,该分配器负责将连续数据段细分为更小的内存块。另一方面,在Linux中,还可以通过直接映射虚拟内存来分配动态内存。为了节省内存,通常只对较大的分配执行此操作,因为它只允许分配页面大小的倍数(通常为4kib)的内存

堆栈也是大量内存使用的一个重要来源,特别是在自动(堆栈)存储中分配大阵列时。堆栈从可用虚拟地址空间的最顶端开始,向下增长。在某些情况下,它可能到达数据段的顶部,或者可能到达其他虚拟分配的末端。坏事情就会发生。堆栈大小在
VmStack
度量和
VmSize
度量中计算。 可以这样概括:

  • VmSize
    负责所有虚拟内存分配(文件映射、共享内存、堆内存、任何内存),并且几乎每次分配新内存时都会增长。几乎是这样,因为如果新的堆内存分配是在数据段中取代已释放的旧分配,则不会分配新的虚拟内存。每当释放虚拟分配时,它都会递减
    VmPeak
    跟踪
    VmSize
    的最大值-它只能随时间增加
  • VmRSS
    随着内存被访问而增加,随着内存被调出到交换设备而减少
  • VmData
    随着堆的数据段部分的使用而增长。它几乎从不收缩,因为当前堆分配器保留释放的内存,以备将来的分配需要
如果您在具有InfiniBand或其他基于RDMA的结构的集群上运行,则会出现另一种内存—锁定(注册)内存(
VmLck
)。这是不允许分页的内存。它如何增长和收缩取决于MPI实现。有些人从不注销已经注册的块(关于为什么这么做的技术细节太复杂,这里无法描述),其他人这样做是为了更好地使用虚拟内存管理器

在您的情况下,您会说您遇到了虚拟内存大小限制。这可能意味着此限制设置得太低,或者您正在运行操作系统强加的限制。首先,Linux(和大多数Unix)有办法通过
ulimit
机制施加人为限制。在shell中运行
ulimit-v
将告诉您虚拟内存大小的限制是多少(以KiB为单位)。您可以使用
ulimit-v
设置限制。这只适用于当前shell生成的进程及其子进程grandchilren等。如果要在远程节点上启动所有其他进程,则需要指示
mpiexec
(或
mpirun
)将此值传播到所有其他进程。如果您是在一些工作负载管理器(如LSF、Sun/Oracle网格引擎、Torque/PBS等)的控制下运行程序,那么有一些作业参数