首页 文章

了解JVM内存分配和Java内存不足:堆空间

提问于
浏览
22

我正在研究真正了解内存分配在JVM中的工作原理 . 我正在编写一个应用程序,其中我将失去内存:堆空间异常 .

我知道我可以将诸如Xms和Xmx之类的VM参数传递给JVM为正在运行的进程分配的堆空间 . 这是问题的一种可能的解决方案,或者我可以检查我的代码是否存在内存泄漏并解决问题 .

我的问题是:

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

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

谢谢 .

4 回答

  • 7

    JVM如何为自己实际分配内存?

    对于堆,它分配一个大的最大内存的连续区域 . 最初这是虚拟存储器,但是随着时间的推移,它在OS的控制下成为所使用部分的真实存储器

    这与操作系统如何将可用内存传递给JVM有何关系?

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

    或者更一般地说,任何进程的内存分配实际上如何工作?

    一般来说,它使用malloc和free .

    虚拟内存如何发挥作用?

    最初分配虚拟内存,这将变为使用的实际内存 . 这对任何过程都是正常的 .

    假设您有一个具有32GB物理内存的系统,并且您将所有32GB分配给您的Java进程 .

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

    假设你的进程实际上消耗了所有32GB的内存,

    假设你有48 GB,并启动一个使用32 GB主内存的进程 .

    我们如何强制使用虚拟内存而不是运行到OOM异常?

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

    通过使用off heap memory,您可以使用比物理更多的内存 . 但是,托管内存必须位于物理内存中,因此如果需要32 GB堆,请购买64 GB主内存 .

  • 21

    想要分配内存的JVM(或任何进程)将调用C运行时'malloc'函数 . 此函数维护C运行时的堆内存 . 反过来,它从操作系统内核获取内存 - 用于此的函数取决于平台;在Linux中它可能正在使用brk or sbrk系统调用 .

    一旦JVM获得了内存,它就会管理内存本身,将其中的一部分分配给正在运行的程序创建的各种对象 .

    虚拟内存完全由操作系统内核处理 . 内核管理物理内存页面到各种进程的地址空间的映射;如果物理内存少于系统中所有进程所需的内存,则OS内核会将其中一些内容交换到磁盘 .

    您不能(也不需要)强制进程使用虚拟内存 . 它对您的流程是透明的 .

    如果您遇到“内存不足”错误,原因很可能是:

    • 超出了JVM限制 . 这些由您在问题中声明的各种命令行参数和/或属性控制

    • 操作系统可能已用完交换空间(或者没有配置任何交换空间以开始) . 或者某些操作系统甚至不支持虚拟内存,在这种情况下,您的实际内存已用完 .

    • 大多数操作系统都有管理员限制进程占用内存量的工具 - 例如,在Linux中使用setrlimit系统调用和/或ulimit shell命令,这两个命令都设置内核将遵守的限制 . 如果进程请求的内存多于限制允许的内存,则尝试将失败(通常会导致内存不足消息) .

  • 2

    这篇博客介绍了Java内存利用率,您可能会发现它很有用:

    http://www.waratek.com/blog/november-2013/introduction-to-real-world-jvm-memory-utilisation

  • 2
    • 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中的空白物理页面中 .

    资料来源:http://searchstorage.techtarget.com/definition/virtual-memory

相关问题