我在Google和此站点中搜索了我的问题,但我仍然不明白该解决方案。
我有一段MPI
程序里面RECV
有一些数据。程序在大型阵列上崩溃,并显示虚拟内存不足的错误,因此我开始考虑/proc/self/status
文件。
在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中,还可以通过直接映射虚拟内存来分配动态内存。通常只对大型分配执行此操作以节省内存,因为它只允许分配页面大小倍数(通常为4
KiB)的内存。
堆栈也是占用大量内存的重要来源,尤其是在自动(堆栈)存储中分配了大阵列的情况下。堆栈从可用虚拟地址空间的顶部开始,然后向下扩展。在某些情况下,它可能到达数据段的顶部,也可能到达其他虚拟分配的末尾。不幸的事情发生了。堆栈大小是在VmStack
度量标准中也包括在内的VmSize
。可以这样总结:
VmSize
占所有虚拟内存分配(文件映射,共享内存,堆内存,任何内存)的份额,并且几乎在每次分配新内存时都会增长。几乎,因为如果在数据段中用新的堆内存分配代替了释放的旧分配,则不会分配新的虚拟内存。每当释放虚拟分配时,它都会减少。VmPeak
跟踪的最大值VmSize
-只能随时间增加。VmRSS
随着访问内存的增加而增加,随着将页面调出到交换设备的次数减少。VmData
随着使用堆的数据段部分而增长。由于当前的堆分配器会保留释放的内存,以防将来的分配需要它,它几乎永远不会收缩。如果您在具有InfiniBand或其他基于RDMA的结构的群集上运行,则另一种内存将起作用-
锁定(注册)的内存(VmLck
)。这是不允许分页的内存。它如何增长和缩小取决于MPI实施。有些人从未取消注册已注册的块(有关其原因的技术细节太复杂,无法在此处描述),其他人则这样做是为了更好地与虚拟内存管理器一起玩。
就您而言,您说您正在遇到虚拟内存大小限制。这可能意味着此限制设置得太低,或者您正在遇到操作系统施加的限制。首先,Linux(和大多数Unix)具有通过该ulimit
机制施加人为限制的手段。ulimit -v
在shell中运行会告诉您KiB中虚拟内存大小的限制是多少。您可以使用设置限制ulimit -v <value in KiB>
。这仅适用于当前shell产生的进程及其子级,grandchilren等。您需要指导mpiexec
(或mpirun
),以将该值传播到所有其他进程(如果要在远程节点上启动它们)。如果您在某些工作负载管理器(例如LSF,Sun
/ Oracle Grid Engine,Torque /
PBS等)的控制下运行程序,则可以使用作业参数来控制虚拟内存大小限制。最后但并非最不重要的一点是,通常将32位进程限制为2 GiB的可用虚拟内存。
问题内容: 我的开发机器上有8GB RAM,并试图运行Apache Tomcat(7.0.29)同时托管Artifactory(2.6.3)和Jenkins(1.479)。我试图找到Jenkins的内存需求,但看起来他们的Wiki断了。 在中,我添加了以下命令: 这应该将Tomcat的JVM的大小保持在(基本上)1到3 GB之间,为我留出足够的空间来容纳其他内容, 并 为Tomcat留出足够的内存
我试图从SSRS服务器读取报告,问题是我的内存流不能超过65536字节。 到目前为止,我已经尝试过使用内存流,但尚未成功设置其容量,然后再阅读报告本身 上面的MemoryStream必须在我读取文件之前增加它的容量。 我试过在我的应用程序中玩。配置,但我不知道从哪里开始设置内存流的字节容量
我想改变(增加)Java内存限制(Windows PC上的JRE)。我到处都遵循以下命令: -xms设置初始Java堆大小 -Xmx设置最大Java堆大小 例如-Xmx1024m。 但我的问题是在哪里!我必须输入这个命令吗?抱歉这个初学者的问题。通常我对java没有任何接触。
我使用“mvn exec:java”运行我的程序: 我没有找到更改JVM的最大内存分配。 我试过-Dexec.commandlineArgs="..."但那不起作用...
我正在使用Spark1.4进行研究,并与内存设置进行斗争。我的机器有16GB内存,所以没有问题,因为我的文件只有300MB。但是,当我试图使用函数将Spark RDD转换为panda dataframe时,我收到以下错误: 我试图修复这个问题,更改了spark-config文件,但仍然得到相同的错误。我听说这是Spark1.4的一个问题,不知道您是否知道如何解决这个问题。任何帮助都是非常感谢的。
问题内容: 嗨,我想知道我可以根据我的应用程序增加JVM的内存。如果是,如何增加JVM的内存?我怎么知道JVM的大小? 问题答案: 启动JVM时,可以调整两个参数以适合你的内存需求: 指定初始Java堆大小,并 最大Java堆大小。 http://www.rgagnon.com/javadetails/java-0131.html