理解 JVM 内存分配和 Java 内存不足:堆空间
我正在研究如何真正了解 JVM 中的内存分配是如何工作的.我正在编写一个内存不足的应用程序:堆空间异常.
I'm looking into really understanding how memory allocation works in the JVM. I'm writing an application in which I'm getting Out of Memory: Heap Space exceptions.
我知道我可以传入 VM 参数(例如 Xms 和 Xmx)来增加 JVM 为正在运行的进程分配的堆空间.这是问题的一种可能解决方案,或者我可以检查我的代码是否存在内存泄漏并在那里解决问题.
I understand that I can pass in VM arguments such as Xms and Xmx to up the heap space that the JVM allocates for the running process. This is one possible solution to the problem, or I can inspect my code for memory leaks and fix the issue there.
我的问题是:
1) JVM 实际上是如何为自己分配内存的?这与操作系统如何将可用内存传递给 JVM 有什么关系?或者更一般地说,任何进程的内存分配实际上是如何工作的?
1) How does the JVM actually allocate memory for itself? How does this relate to how the OS communicates available memory to the JVM? Or more generally, how does memory allocation for any process actually work?
2) 虚拟内存是如何发挥作用的?假设您有一个具有 32GB 物理内存的系统,并且您将所有 32GB 分配给您的 Java 进程.假设您的进程实际上消耗了所有 32GB 内存,我们如何强制该进程使用虚拟内存而不是遇到 OOM 异常?
2) 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. Let's say that your process actually consumes all 32GB of memory, how can we enforce the process to use virtual memory instead of running into OOM exceptions?
谢谢.
推荐答案
JVM 是如何为自己实际分配内存的?
How does the JVM actually allocate memory for itself?
对于堆,它分配一个最大的连续大内存区域.最初这是虚拟内存,但随着时间的推移,它会在操作系统的控制下变成实际内存,用于使用的部分.
For the heap it allocate one large continuous region of memory of the maximum size. Initially this is virtual memory however, over time it becomes real memory for the portions which are used, under control of the OS
这与操作系统如何将可用内存传递给 JVM 有什么关系?
How does this relate to how the OS communicates available memory to the JVM?
JVM 不知道操作系统中的空闲内存.
The JVM has no idea about free memory in the OS.
或者更一般地说,任何进程的内存分配实际上是如何工作的?
Or more generally, how does memory allocation for any process actually work?
一般它使用malloc和free.
In general it uses malloc and free.
虚拟内存是如何发挥作用的?
How does virtual memory come into play?
最初分配了虚拟内存,这会变成实际使用的内存.这对于任何进程都是正常的.
Initially virtual memory is allocated and this turns into real memory as used. This is normal for any process.
假设您有一个具有 32GB 物理内存的系统,并且您将所有 32GB 分配给您的 Java 进程.
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 堆.
You can't. The OS need some memory and there will be memory for other purposes. Even within the JVM the heap is only a portion of the memory used. If you have 32 GB of memory I suggest as 24 GB heap max.
假设你的进程实际上消耗了全部 32GB 内存,
Let's say that your process actually consumes all 32GB of memory,
假设您有 48 GB,并且您启动了一个使用 32 GB 主内存的进程.
Say you have 48 GB and you start a process which uses 32 GB of main memory.
我们如何强制进程使用虚拟内存而不是遇到 OOM 异常?
how can we enforce the process to use virtual memory instead of running into OOM exceptions?
应用程序从一开始就使用虚拟内存.你不能让堆太大,因为如果它开始交换你的机器(不仅仅是你的应用程序)将变得不可用.
The application uses virtual memory right from the start. You cannot make the heap too large because if it starts swapping your machine (not just your application) will become unusable.
小心使用堆外内存,您可以使用比物理内存更多的内存.但是托管内存必须在物理内存中,因此如果您需要 32 GB 堆,请购买 64 GB 主内存.
You can use more memory than you have physical by using off heap memory, carefully. However managed memory must be in physical memory so if you need a 32 GB heap, buy 64 GB of main memory.
相关文章