JVM内存分为堆(heap)、方法区(method area)、虚拟机栈(vm stack)、本地方法栈(native method stack)、程序计数器。
其中堆、方法区是线程共享;虚拟机栈、本地方法栈和程序计数器是线程独享。
程序计数器
程序技术器记录java程序下一条需要执行的指令, 因为jvm实现线程是共享cpu, 就是在某一时刻,当一个线程占用处理器(对于多核处理器来说是一个内核)时, 另一线程处于等待状态,当线程切换时, 为了保证线程的代码能正确执行,程序计数器必须线程独有。
程序计数器没有内存溢出。
虚拟机栈
虚拟机栈随着线程的建立而建立,线程结束后销毁。一个java线程可能调用多个方法,当方法被调用时,响应度栈帧被压入栈, 栈帧中保存着方法的局部变量、返回地址等信息。
本地方法栈当栈深度大于虚拟机所允许的深度,将抛出StackOverflowError;
栈在扩展过程中,无法申请到足够的内存控件,则抛出OutOfMemoryError:unable to create new native thread
可通过配置 -Xss参数设置栈大小。
本地方法栈
用于管理java本地方法。 sun的hotspot虚拟机将java本地方法栈和虚拟机栈合二为一。
堆
Java的堆保存所有java动态创建的对象信息, 是jvm中内存中最大一块。
堆内存溢出后, 错误信息如下:
java.lang.OutOfMemoryError: Java heap space
可通过堆参数(-Xmx与-Xms)配置堆大小。建议将-Xms、-xmx设置为同样大小,这样可以避免尹扩展内存而引起的性能问题。
方法区
方法区保存java中类信息和常量信息。
方法区内存溢出时, 错误信息如下:
java.lang.OutOfMemoryError: PermGenspace
设置方法区内存大小可以通过: -XX:PermSize/-XX:MaxPermSize
直接内存区
直接内存区是非堆栈所属内存区, 例如NIO类,它使用native方法在堆栈外直接分配内存,并在JVM内部拥有该内存的应用,减少了数据从jvm外到堆的copy过程, 从而提高了效率。
直接内存区内存大小 + 堆栈内存区大小 < 机器总内存大小。
直接内存溢出错误如下:
java.lang.OutOfMemoryError:
本文详细解析了Java虚拟机内存的组成,包括堆、方法区、虚拟机栈、本地方法栈和程序计数器,解释了它们的作用及如何管理内存以避免错误。
381

被折叠的 条评论
为什么被折叠?



