了解 JVM 内存分配和 Java 内存不足:堆空间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21272877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Understanding JVM Memory Allocation and Java Out of Memory: Heap Space
提问by HiChews123
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.
我正在研究真正了解内存分配在 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.
我知道我可以传入诸如 Xms 和 Xmx 之类的 VM 参数来增加 JVM 为正在运行的进程分配的堆空间。这是该问题的一种可能解决方案,或者我可以检查我的代码是否存在内存泄漏并在那里解决问题。
My questions are:
我的问题是:
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?
1)JVM实际上是如何为自己分配内存的?这与操作系统如何将可用内存通信给 JVM 有什么关系?或者更一般地说,任何进程的内存分配实际上是如何工作的?
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?
2)虚拟内存如何发挥作用?假设您有一个具有 32GB 物理内存的系统,并且您将所有 32GB 分配给您的 Java 进程。假设您的进程实际上消耗了全部 32GB 内存,我们如何强制该进程使用虚拟内存而不是遇到 OOM 异常?
Thanks.
谢谢。
采纳答案by Peter Lawrey
How does the JVM actually allocate memory for itself?
JVM 是如何为自己分配内存的?
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
对于堆,它分配一个最大大小的连续大内存区域。最初这是虚拟内存,但是,随着时间的推移,它在操作系统的控制下成为所使用部分的真实内存
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.
JVM 不知道操作系统中的空闲内存。
Or more generally, how does memory allocation for any process actually work?
或者更一般地说,任何进程的内存分配实际上是如何工作的?
In general it uses malloc and free.
通常它使用 malloc 和 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.
最初分配虚拟内存,并在使用时变成实内存。这对于任何过程都是正常的。
Let's say you have a system with 32GB of physical memory and you allocate all 32GB to your Java process.
假设您有一个具有 32GB 物理内存的系统,并且您将所有 32GB 分配给您的 Java 进程。
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.
你不能。操作系统需要一些内存,并且会有用于其他目的的内存。即使在 JVM 中,堆也只是所用内存的一部分。如果您有 32 GB 的内存,我建议最大为 24 GB 堆。
Let's say that your process actually consumes all 32GB of memory,
假设您的进程实际上消耗了全部 32GB 内存,
Say you have 48 GB and you start a process which uses 32 GB of main memory.
假设您有 48 GB,并且您启动了一个使用 32 GB 主内存的进程。
how can we enforce the process to use virtual memory instead of running into OOM exceptions?
我们如何强制进程使用虚拟内存而不是遇到 OOM 异常?
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.
该应用程序从一开始就使用虚拟内存。你不能让堆太大,因为如果它开始交换你的机器(不仅仅是你的应用程序)将变得不可用。
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.
通过谨慎使用堆外内存,您可以使用比物理内存更多的内存。但是托管内存必须在物理内存中,因此如果您需要 32 GB 的堆,请购买 64 GB 的主内存。
回答by Little Child
The JVM allocates Java heap memory from the OS and then manages the heap for the Java application. When an application creates a new object, the JVM sub-allocates a contiguous area of heap memory to store it. An object in the heap that is referenced by any other object is "live," and remains in the heap as long as it continues to be referenced. Objects that are no longer referenced are garbage and can be cleared out of the heap to reclaim the space they occupy. The JVM performs a garbage collection (GC) to remove these objects, reorganizing the objects remaining in the heap.
Source: http://pubs.vmware.com/vfabric52/index.jsp?topic=/com.vmware.vfabric.em4j.1.2/em4j/conf-heap-management.htmlIn a system using virtual memory, the physical memory is divided into equally-sized pages. The memory addressed by a process is also divided into logical pages of the same size. When a process references a memory address, the memory manager fetches from disk the page that includes the referenced address, and places it in a vacant physical page in the RAM.
JVM 从操作系统分配 Java 堆内存,然后为 Java 应用程序管理堆。当应用程序创建一个新对象时,JVM 会子分配一个连续的堆内存区域来存储它。被任何其他对象引用的堆中的对象是“活动的”,并且只要它继续被引用就一直留在堆中。不再被引用的对象是垃圾,可以从堆中清除以回收它们占用的空间。JVM 执行垃圾回收 (GC) 以删除这些对象,重新组织堆中剩余的对象。
来源:http: //pubs.vmware.com/vfabric52/index.jsp?topic=/com.vmware.vfabric.em4j.1.2/em4j/conf-heap-management.html在使用虚拟内存的系统中,物理内存被划分为大小相等的页面。进程寻址的内存也被划分为相同大小的逻辑页。当进程引用内存地址时,内存管理器从磁盘获取包含引用地址的页面,并将其放置在 RAM 中的空闲物理页面中。
Source: http://searchstorage.techtarget.com/definition/virtual-memory
来源:http: //searchstorage.techtarget.com/definition/virtual-memory
回答by harmic
The JVM (or for that matter any process) that wants to allocate memory will call the C runtime 'malloc' function. This function maintains the heap memory of the C runtime. It, in turn, obtains memory from the operating system kernel - the function used for this is platform dependent; in Linux it could be using the brk or sbrksystem calls.
想要分配内存的 JVM(或就此而言的任何进程)将调用 C 运行时的“ malloc”函数。该函数维护 C 运行时的堆内存。反过来,它从操作系统内核获取内存——用于此的函数是平台相关的;在 Linux 中,它可以使用brk 或 sbrk系统调用。
Once the memory has been obtained by the JVM, it manages the memory itself, allocating parts of it to the various objects created by the running program.
一旦 JVM 获得了内存,它就会管理内存本身,将其中的一部分分配给运行程序创建的各种对象。
Virtual memory is handled entirely by the operating system kernel. The kernel manages mapping of physical memory pages to the address space of various processes; if there is less physical memory than is needed by all the processes in the system then the OS Kernel will swap some of it out to disk.
虚拟内存完全由操作系统内核处理。内核管理物理内存页到各个进程地址空间的映射;如果物理内存少于系统中所有进程所需的物理内存,那么操作系统内核会将其中的一部分交换到磁盘上。
You can't (and don't need to) force processes to use Virtual Memory. It is transparent to your process.
您不能(也不需要)强制进程使用虚拟内存。它对您的过程是透明的。
If you are getting 'out of memory' errors, then the causes are likely to be:
如果您遇到“内存不足”错误,那么原因可能是:
The JVM limits are being exceeded. These are controlled by various command line arguments and/or properties as you stated in your question
The OS may have run out of swap space (or not have any swap space configured to start with). Or some OSs don't even support virtual memory, in which case you have run out of real memory.
Most OSs have facilities for the administrator to limit the amount of memory consumed by a process - for example, in Linux the setrlimitsystem call and/or the ulimit shell command, both of which set limits that the kernel will observe. If a process requests more memory than is allowed by the limits, then the attempt will fail (typically this results in an out of memory message).
正在超出 JVM 限制。正如您在问题中所述,这些由各种命令行参数和/或属性控制
操作系统可能已用完交换空间(或没有配置任何交换空间开始)。或者某些操作系统甚至不支持虚拟内存,在这种情况下,您的实际内存已用完。
大多数操作系统都有供管理员限制进程消耗的内存量的工具——例如,在 Linux 中,setrlimit系统调用和/或 ulimit shell 命令,这两者都设置了内核将遵守的限制。如果进程请求的内存超过限制允许的数量,则尝试将失败(通常这会导致内存不足消息)。
回答by ElastiCat
This blog looks at Java memory utilisation which you might find useful:
这篇博客着眼于 Java 内存利用率,您可能会发现它很有用:
http://www.waratek.com/blog/november-2013/introduction-to-real-world-jvm-memory-utilisation
http://www.waratek.com/blog/november-2013/introduction-to-real-world-jvm-memory-utilisation