java - 了解 JVM 内存分配和 Java 内存不足 : Heap Space

标签 java memory memory-management jvm out-of-memory

我正在研究如何真正了解 JVM 中的内存分配是如何工作的。 我正在编写一个内存不足的应用程序:堆空间异常。

我知道我可以传入 VM 参数(例如 Xms 和 Xmx)来增加 JVM 为正在运行的进程分配的堆空间。这是问题的一种可能解决方案,或者我可以检查我的代码是否存在内存泄漏并在那里解决问题。

我的问题是:

1) JVM 实际上是如何为自己分配内存的?这与操作系统如何将可用内存传递给 JVM 有什么关系?或者更一般地说,任何进程的内存分配实际上是如何工作的?

2) 虚拟内存是如何发挥作用的?假设您有一个具有 32GB 物理内存的系统,并且您将所有 32GB 分配给您的 Java 进程。假设您的进程实际上消耗了所有 32GB 内存,我们如何强制该进程使用虚拟内存而不是遇到 OOM 异常?

谢谢。

最佳答案

How does the JVM actually allocate memory for itself?

对于堆,它分配一个最大的连续大内存区域。最初这是虚拟内存,但随着时间的推移,它会在操作系统的控制下变成实际内存,用于使用的部分。

How does this relate to how the OS communicates available memory to the JVM?

JVM 不知道操作系统中的空闲内存。

Or more generally, how does memory allocation for any process actually work?

一般它使用malloc和free。

How does virtual memory come into play?

最初分配了虚拟内存,这会变成实际使用的内存。这对于任何进程都是正常的。

Let's say you have a system with 32GB of physical memory and you allocate all 32GB to your Java process.

你不能。操作系统需要一些内存,并且会有用于其他目的的内存。即使在 JVM 中,堆也只是使用的内存的一部分。如果您有 32 GB 的内存,我建议您使用最大 24 GB 堆。

Let's say that your process actually consumes all 32GB of memory,

假设您有 48 GB,并且您启动了一个使用 32 GB 主内存的进程。

how can we enforce the process to use virtual memory instead of running into OOM exceptions?

应用程序从一开始就使用虚拟内存。你不能让堆太大,因为如果它开始交换你的机器(不仅仅是你的应用程序)将变得不可用。

小心使用堆外内存,您可以使用比物理内存更多的内存。但是托管内存必须在物理内存中,因此如果您需要 32 GB 堆,请购买 64 GB 主内存。

关于java - 了解 JVM 内存分配和 Java 内存不足 : Heap Space,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21272877/

相关文章:

java - HTML重定向

java - Android 如何播放 Assets 文件夹中的媒体文件 (.mp4)

c# - 监控应用程序内存使用情况的正确方法是什么?

linux - mmap 与 malloc : strange performance

c - 如何将链表中的节点分割成 8 字节的 block ?

java - Java 中二维数组/矩阵的扩展大小

java - 调用批处理运行jar的方法

c++ - C++ 什么时候从内存中删除变量?

linux - Linux 中的直接内存访问

c - 为什么有人会在 C 中初始化未分配的内存?