可以通过运行jstat-gc(PID)命令在运行时查看元空间内存的使用情况
另外一个问题:
java应用程序的本机内存(Metaspace)是从堆内存获得空间,还是有一组完全不同的内存专用于它?
答:
Java堆空间
Java堆空间由Java运行时用来为对象和JRE类分配内存。每当我们创建任何对象时,它总是在堆空间中创建的。垃圾回收在堆内存上运行,以释放没有任何引用的对象所使用的内存。在堆空间中创建的任何对象都具有全局访问权限,并且可以从应用程序的任何位置引用。
Java堆栈内存
Java堆栈内存用于执行线程。它们包含特定于方法的短期值以及对堆中从该方法引用的其他对象的引用。堆栈内存总是以后进先出(后进先出)顺序引用。每当调用一个方法时,都会在堆栈内存中为该方法创建一个新的块来保存本地基元值和对方法中其他对象的引用。一旦方法结束,该块就变为未使用并可用于下一个方法。与堆内存相比,堆栈内存的大小非常小。
Java堆空间heap和堆栈内存stack的区别
堆内存由应用程序的所有部分使用,而堆栈内存仅由一个执行线程使用。
每当创建对象时,它总是存储在堆空间中,堆栈内存包含对它的引用。堆栈内存只包含本地基元变量和堆空间中对象的引用变量。
堆中存储的对象是全局可访问的,而堆栈内存则不能被其他线程访问。
堆栈中的内存管理是以后进先出的方式进行的,而在堆内存中则更复杂,因为它是全局使用的。堆内存分为年轻一代、老一代等,更多细节请看Java垃圾回收。
堆栈内存是短暂的,而堆内存从应用程序执行的开始一直持续到结束。
我们可以使用-Xms和-xmxjvm选项来定义堆内存的启动大小和最大大小。我们可以使用-Xss来定义堆栈内存大小。
当堆栈内存已满时,Java运行时抛出java.lang.StackOverflower而如果堆内存已满,则会抛出java.lang.OutOfMemoryError:Java堆空间错误。
与堆内存相比,堆栈内存的大小非常小。由于内存分配(LIFO)的简单性,与堆内存相比,堆栈内存非常快。
下图显示了与上述程序相关的堆栈和堆内存,以及它们如何用于存储基元、对象和引用变量
让我们来看看程序的执行步骤:
- 一旦我们运行程序,它就会将所有运行时类加载到堆空间中。当main()方法在第1行找到时,Java运行时会创建堆栈内存供main()方法线程使用。
- 我们在第2行创建原始局部变量,因此它被创建并存储在main()方法的堆栈内存中。
- 因为我们在第三行创建一个对象,所以它是在堆内存中创建的,堆栈内存包含对它的引用。当我们在第四行创建内存对象时,也会发生类似的过程。
- 现在,当我们在第5行调用foo()方法时,会在堆栈顶部创建一个块供foo()方法使用。由于Java是通过值传递的,所以在第6行的foo()堆栈块中创建了对对象的新引用。
- 在第7行创建一个字符串,它进入堆空间的字符串池,并在foo()堆栈空间中为它创建一个引用。
- foo()方法在第8行终止,此时堆栈中为foo()分配的内存块变为空闲。
- 在第9行中,main()方法终止,并销毁为main()方法创建的堆栈内存。另外,程序在这一行结束,因此Java运行时释放所有内存并结束程序的执行。
除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/381.html
暂无评论