问题标签 [virtual-memory]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
36516 浏览

solaris - prstat 输出中 SIZE 和 RSS 值的含义

有人可以对我们从 Solaris 中的 prstat 获得的 SIZE 和 RSS 值的含义给出一些明确的解释吗?

我编写了一个测试 C++ 应用程序,它用 分配内存new[]、填充它并用delete[].

据我了解,SIZE 值应该与进程“保留”多少虚拟内存有关,即内存“分配”或“新”。

除非我真的使用它(填充一些值),否则该内存不会汇总在 RSS 值中。但是,即使我释放内存,RSS 也不会下降。

我不明白我可以正确分配给这两个值的语义。

0 投票
3 回答
4364 浏览

asp.net - 确定谁/什么在 w3wp.exe 中保留了 5.5 GB 的虚拟内存

在我的机器(XP,64)上,ASP.net 工作进程(w3wp.exe)总是在启动时保留 5.5GB 的虚拟内存。无论它托管的 Web 应用程序如何(它可以是任何东西,甚至是 aspx 中的空网页),都会发生这种情况。

这个大的旧虚拟内存块在进程开始时被保留,所以这不是某种逐渐的内存“泄漏”。

对windbg 的一些窥探表明,内存问题是Private、Reserved 和RegionUsageIsVAD,这表明它可能是调用VirtualAlloc 的人的工作。它还表明,有问题的内存被分配/保留为 4 个大块,每个 1GB 和几个较小的块(每个 1/4GB)。

所以我想我需要弄清楚谁在调用 VirtualAlloc 并保留所有这些内存。我怎么做?

在分配内存之前将调试器附加到进程是很棘手的,因为 w3wp.exe 是由 svchost.exe(即 IIS/ASP.Net 过滤器)启动的进程,如果我尝试自己启动它以调试它它只是在没有所有这些大量内存保留的情况下关闭。此外,如果我重用它们,命令行参数是无效的(这是有道理的,因为它是由调用进程创建的管道)。

我可以在事后将它附加到进程中(这就是我找到有问题的内存区域的方式),但我不确定当时是否有可能确定谁分配了什么。

0 投票
8 回答
263844 浏览

java - Linux下Java的虚拟内存使用情况,使用的内存过多

我对在 Linux 下运行的 Java 应用程序有疑问。

当我使用默认的最大堆大小 (64 MB) 启动应用程序时,我看到使用 tops 应用程序为应用程序分配了 240 MB 的虚拟内存。这会给计算机上的其他一些软件带来一些问题,这些软件资源相对有限。

据我了解,保留的虚拟内存无论如何都不会被使用,因为一旦我们达到堆限制,OutOfMemoryError就会抛出一个。我在 windows 下运行了相同的应用程序,我看到虚拟内存大小和堆大小相似。

无论如何,我可以为 Linux 下的 Java 进程配置正在使用的虚拟内存吗?

编辑1:问题不在于堆。问题是,如果我设置一个 128 MB 的堆,例如,Linux 仍然分配 210 MB 的虚拟内存,这永远不需要。**

编辑 2:使用ulimit -v允许限制虚拟内存的数量。如果设置的大小低于 204 MB,则应用程序将不会运行,即使它不需要 204 MB,只需要 64 MB。所以我想了解为什么 Java 需要这么多虚拟内存。这可以改变吗?

编辑 3:系统中运行着其他几个应用程序,这些应用程序是嵌入式的。而且系统确实有虚拟内存限制(来自评论,重要细节)。

0 投票
7 回答
1187 浏览

java - 告诉 Java 不要将对象推入交换空间

是否可以告诉 JVM 提示操作系统最好不要将某个对象推出交换空间?

0 投票
5 回答
3096 浏览

java - 有没有办法在从 NetBeans 启动的应用程序中增加虚拟内存?

在我的项目中,我经常遇到Java堆空间错误,即没有足够的空间来运行程序。有什么办法可以增加虚拟内存?

我没有使用命令行。我正在使用 Net Beans。

0 投票
15 回答
11456 浏览

c++ - 如何避免在高内存使用应用程序中耗尽内存?C / C++

我编写了一个转换器,它接受 openstreetmap xml 文件并将它们转换为二进制运行时渲染格式,该格式通常约为原始大小的 10%。输入文件大小通常为 3gb 或更大。输入文件不会一次全部加载到内存中,而是在收集点和多边形时进行流式传输,然后在它们上运行 bsp 并输出文件。最近在较大的文件上,它会耗尽内存并死掉(有问题的文件有 1400 万个点和 100 万个多边形)。通常,当这种情况发生时,我的程序使用大约 1gb 到 1.2gb 的内存。我尝试将虚拟内存从 2 增加到 8GB(在 XP 上),但这种更改没有效果。此外,由于此代码是开源的,我希望它能够在任何可用内存(尽管速度较慢)的情况下运行,它可以在 Windows、Linux 和 Mac 上运行。

我可以使用哪些技术来避免内存不足?在较小的子集中处理数据,然后合并最终结果?使用我自己的虚拟内存类型的处理程序?还有其他想法吗?

0 投票
6 回答
2012 浏览

linux - 遗留 gcc 编译器问题

我们正在使用基于 gcc 2.6.0 的旧版编译器来交叉编译我们仍在使用的旧嵌入式处理器(是的,它自 1994 年以来仍在使用!)。为这个芯片做 gcc 端口的工程师早就离开了。虽然我们可能能够从网络上的某个地方恢复 gcc 2.6.0 源,但该芯片的更改集已经在公司历史的大厅中消失了。直到最近,我们一直在糊涂,因为编译器仍在运行并生成可运行的可执行文件,但从 linux 内核 2.6.25(以及 2.6.26)开始,它会失败并显示消息gcc: virtual memory exhausted... 即使在没有参数或仅使用-v. 我已经使用 2.6.24 内核重新启动了我的开发系统(从 2.6.26 开始)并且编译器再次工作(使用 2.6.25 重新启动不会)。

我们有一个系统保持在 2.6.24,只是为了构建这个芯片,但是感觉有点暴露,以防 linux 世界发展到我们不能再重建一个可以运行的系统编译器(即我们的 2.6.24 系统死掉了,我们无法在新系统上安装和运行 2.6.24,因为某些软件部分不再可用)。

有没有人知道我们可以对更现代的安装做些什么来让这个遗留编译器运行?

编辑

回答一些评论...

可悲的是,丢失了特定于我们芯片的源代码更改。这种损失发生在两个主要的公司重组和几个系统管理员(其中几个确实留下了一个烂摊子)。我们现在使用配置控制,但这对于这个问题来说太迟了。

使用虚拟机是一个好主意,并且可能是我们最终要做的事情。谢谢你的想法。

最后,我按照ehemient的建议尝试了strace,发现最后一个系统调用是brk(),在新系统(2.6.26内核)上返回错误,在旧系统(2.6.24内核)上返回成功。这表明我的虚拟内存真的用完了,除了 tcsh "limit" 在旧系统和新系统上返回相同的值,并且 /proc/meminfo 显示新系统有更多的内存和更多的交换空间。也许是碎片问题或程序加载的位置?

我做了一些进一步的研究,并在内核 2.6.25 中添加了“brk 随机化”,但CONFIG_COMPAT_BRK据说默认启用(禁用 brk 随机化)。

编辑

好的,更多信息:看起来 brk 随机化确实是罪魁祸首,旧版 gcc 正在调用 brk() 来更改数据段的结尾,现在失败了,导致旧版 gcc 报告“虚拟内存耗尽”。有一些记录在案的方法可以禁用 brk 随机化:

  • sudo echo 0 > /proc/sys/kernel/randomize_va_space

  • sudo sysctl -w kernel.randomize_va_space=0

  • setarch i386 -R tcsh用(或“-R -L”)开始一个新的shell

我已经尝试过它们,它们似乎确实有效果,因为 brk() 返回值与没有它们时不同(并且始终相同)(在内核 2.6.25 和 2.6.26 上都尝试过),但是 brk()仍然失败,所以旧版 gcc 仍然失败:-(。

此外,我已经设置vm.legacy_va_layout=1并且vm.overcommit_memory=2没有任何更改,并且我已经使用/etc/sysctl.conf 中保存的设置vm.legacy_va_layout=1重新启动。kernel.randomize_va_space=0还是没有变化。

编辑

在内核 2.6.26(和 2.6.25)上使用kernel.randomize_va_space=0会导致以下 brk() 调用被报告strace legacy-gcc

brk(0x80556d4) = 0x8056000

这表明 brk() 失败,但看起来它失败了,因为数据段已经超出了请求的范围。使用 objdump,我可以看到数据段应该在 0x805518c 结束,而失败的 brk() 表明数据段当前在 0x8056000 结束:

编辑

在下面回应 ehemient 的评论:“将 GCC 视为没有源代码的二进制文件真是太奇怪了”!

因此,使用 strace、objdump、gdb 以及我对 386 汇编器和体系结构的有限理解,我将问题追溯到遗留代码中的第一个 malloc 调用。旧版 gcc 调用 malloc,它返回 NULL,这会导致 stderr 上出现“虚拟内存耗尽”消息。这个 malloc 在 libc.so.5 中,它多次调用 getenv 并最终调用 brk()...我想增加堆...失败了。

由此我只能推测问题不仅仅是 brk 随机化,或者我没有完全禁用 brk 随机化,尽管 randomize_va_space=0 和 legacy_va_layout=1 sysctl 设置。

0 投票
5 回答
39111 浏览

memory - 如何使用页表将虚拟地址转换为物理地址?

假设我有一个普通的页表:

页表(页面大小 = 4k)

如何将任意逻辑地址(如 51996)转换为物理内存地址?


如果我取 log base 2 (4096),我得到 12。我认为这是我应该使用多少位来偏移地址。

我只是不确定。51996 / 4096 = 12.69。那么这是否意味着它以一定的偏移量位于第 12 页上?

那我怎么把它变成“51996”的物理地址呢?

0 投票
9 回答
12166 浏览

windows - 64 位大型 malloc

malloc() 失败的原因是什么,尤其是在 64 位中?

我的具体问题是试图在 64 位系统上分配 10GB 的巨大 RAM 块。这台机器有 12GB 的 RAM 和 32GB 的交换空间。是的,malloc 是极端的,但为什么会有问题呢?这是在带有 Intel 和 MSFT 编译器的 Windows XP64 中。malloc 有时会成功,有时不会,大约 50%。8GB malloc 总是有效,20GB malloc 总是失败。如果 malloc 失败,重复请求将不起作用,除非我退出该进程并再次启动一个新进程(然后将有 50% 的成功率)。没有其他大型应用程序正在运行。它甚至在重新启动后立即发生。

如果您用完了可用的 32(或 31)位地址空间,我可以想象 malloc 在 32 位中失败,这样就没有足够大的地址范围来分配给您的请求。

如果你用完了物理 RAM硬盘交换空间,我也可以想象 malloc 会失败。这不是我的情况。

但是为什么 malloc 会失败呢?我想不出其他原因。

我对一般 malloc 问题比我的具体示例更感兴趣,无论如何我可能会用内存映射文件替换它。失败的 malloc() 比其他任何事情都更像是一个谜……渴望了解您的工具而不是对基本原理感到惊讶。

0 投票
5 回答
848 浏览

windows - 防止繁重的进程沉入交换文件

我们的服务往往在晚上在我们客户的服务器上睡着,然后很难醒来。似乎发生的情况是,有时数百 MB 的进程堆被移动到交换文件中。这发生在晚上,当我们的服务未被使用,而其他服务被安排运行(数据库备份、反病毒扫描等)时。发生这种情况时,在几个小时不活动后,对服务的第一次调用最多需要几分钟(后续调用需要几秒钟)。

我很确定这是虚拟内存管理的问题,我真的很讨厌强迫操作系统将我们的服务保留在物理内存中的想法。我知道这样做会损害服务器上的其他进程,并降低整体服务器吞吐量。话虽如此,我们的客户只是希望我们的应用程序能够响应。他们不在乎夜间工作是否需要更长的时间。

我隐约记得有一种方法可以强制 Windows 将页面保留在物理内存上,但我真的很讨厌这个想法。我更倾向于一些内部或外部的看门狗,它们将启动更高级别的功能(已经有一些内部调度程序做的很少,并且没有区别)。如果有提供这种服务的第 3 方工具会同样好。

我很想听听针对此类问题的任何意见、建议和常见解决方案。该服务是用VC2005编写的,运行在Windows服务器上。