Java 堆空间和 RAM

标签 java jvm heap-memory jvm-hotspot

在阅读了一篇关于分析线程转储的文章后,我有一个问题困扰着我。有一段提到 32 位 JVM 中的逻辑最大堆大小为 4GB。

This链接指出 32 位 Windows 机器上的最大堆大小约为 1.4 - 1.6 GB。

我的问题是,假设您有大约 8GB 的​​ RAM,这是否意味着如果我是 32 位 JVM,我只能使用其中的 1.4-1.6 GB? 64 位 JVM 允许的最大大小是多少?

感谢您对此的帮助,因为我对此感到困惑。

最佳答案

特别是在 windows 上,原因是热点(sun/oracle JVM)和 windows dll 的实现的组合。

32 位代码可以访问 4GB 的虚拟地址空间(有些扩展允许更多,但我不会讨论这些)。

在 32 位 Windows 上,此虚拟地址空间的上部 2GB 保留供操作系统使用(某些版本的操作系统接受 /3GB 标志作为引导参数以允许 3GB 的用户可访问空间)。

此外,您使用的任何库 (*.dll) 都映射到该地址空间的一部分。默认情况下,Windows 基础 *.dll 文件加载到 ~1.6 GB 标记处(操作系统版本和补丁级别略有不同)

最重要的是,热点 JVM 仅支持分配单个连续的内存块用作堆空间。

因此,如果您尝试在脑海中想象一下,您会发现您有一个大约 2GB 的可用区域,其中有一堵加载了大约 1.6GB 的 Windows *.dll 的“墙”。这就是该数字背后的逻辑。这也意味着即使您提供了/3GB 标志,sun/oracle JVM 也无法使用它。其他一些虚拟机更擅长处理碎片化的堆——比如 jrockit VM

你也可以试试 rebasing windows dlls以便它们加载到更高的内存地址并挤压一些更多可用的堆空间,但是这个过程是脆弱的。

还请注意,加载到特定机器上的驱动程序/应用程序(如反病毒软件)很可能会将它们自己的 *.dll 注入(inject)到 java 进程中,并且这些 dll 可以加载到更低的内存地址,进一步缩小您的可用堆空间。

在 64 位版本的 Windows 上 the addressable limit is 8-128TB物理限制现在是 64TB

关于Java 堆空间和 RAM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21631167/

相关文章:

java - 使用 jigsaw 模块通过 jdk9 运行 spring boot

java - 关于Java并发的概念问题

java - Java-如何使我的代码使用更少的内存?

java - 如何增加 Eclipse ADT Bundle 的 Java 堆空间

java - 使用 selenium 中的机器人类上传文件在远程计算机上工作正常,但在远程连接关闭时失败

java - 为什么我的 Oracle JVM 会为一个简单的 'Hello World' 程序创建所有这些对象?

java - 字节码中丢失变量 'final' 修饰符?

winapi - 我如何告诉 MS CRT 在 Windows XP 上使用低碎片堆?

c++ - 为什么我需要使用动态内存分配,而我可以从静态中实现相同的目的?

java - 未实现的接口(interface)有什么用?