【发布时间】:2016-12-29 06:10:20
【问题描述】:
Java 应用程序的本机内存(元空间)是从堆内存中获取空间,还是有一组完全不同的内存专用于它?
我认为它使用操作系统使用的内存来管理所有应用程序,但不清楚。
【问题讨论】:
Java 应用程序的本机内存(元空间)是从堆内存中获取空间,还是有一组完全不同的内存专用于它?
我认为它使用操作系统使用的内存来管理所有应用程序,但不清楚。
【问题讨论】:
Java 堆空间
Java 运行时使用 Java 堆空间为对象和 JRE 类分配内存。每当我们创建任何对象时,它总是在堆空间中创建。垃圾回收在堆内存上运行,以释放没有任何引用的对象使用的内存。在堆空间中创建的任何对象都具有全局访问权限,并且可以从应用程序的任何位置引用。
Java 堆栈内存
Java Stack 内存用于执行线程。它们包含短暂的方法特定值以及对堆中从方法引用的其他对象的引用。堆栈内存始终以 LIFO(后进先出)顺序引用。每当调用方法时,都会在堆栈内存中创建一个新块,用于该方法保存本地原始值并引用该方法中的其他对象。一旦方法结束,该块将变为未使用并可供下一个方法使用。堆栈内存大小与堆内存相比要小得多。
Java 堆空间和栈内存的区别
堆内存由应用程序的所有部分使用,而堆栈内存仅由一个执行线程使用。
每当创建一个对象时,它总是存储在堆空间中,堆栈内存包含对它的引用。栈内存只包含局部原始变量和堆空间中对象的引用变量。
堆中存储的对象可以全局访问,而堆栈内存不能被其他线程访问。
堆栈中的内存管理以 LIFO 方式完成,而堆内存中则更复杂,因为它是全局使用的。堆内存分为Young-Generation、Old-Generation等,更多详情见Java Garbage Collection。
堆栈内存是短暂的,而堆内存从应用程序执行开始到结束都存在。
我们可以使用 -Xms 和 -Xmx JVM 选项来定义堆内存的启动大小和最大大小。我们可以使用-Xss来定义栈内存大小。
当堆栈内存已满时,Java 运行时会抛出 java.lang.StackOverFlowError,而如果堆内存已满,则会抛出 java.lang.OutOfMemoryError: Java Heap Space 错误。
与堆内存相比,堆栈内存大小非常小。由于内存分配 (LIFO) 的简单性,堆栈内存与堆内存相比非常快。
参考:
这是 Java 内存管理的基础知识,但是通过参考资料应该会给你一个全面的想法。
编辑
感谢@rajvineet 指出how the JVM uses native memory on Windows and Linux 上的这篇精彩文章。特别是 how the Java runtime uses native memory 部分清楚地描述了所有内容。
【讨论】: