如果虚拟机栈可以动态扩展, 扩展时无法申请做够的内存, 将会爬出 OutOfMemorryError
本地方法栈
与虚拟机栈发挥的作用非常类似, 他们之间的区别是虚拟机栈为虚拟机执行 java 方法服务, 而本地方法栈则为虚拟机使用到的 native 方法服务. 与虚拟机栈一样, 本地房发展区域也会抛出 StackOverflowError,OutOfMemorryError 异常.
方法区 (1.8 后该区域被废弃)
方法区与 java 堆一样, 是各个线程所共享的, 它用来存储已被虚拟机加载的类信息, 常量, 静态变量, 即时编译后的代码等数据.
方法区是 jvm 提出的规范, 而永久代就是方法区的具体实现.
java 虚拟机对方法区的限制非常宽松, 可以像堆一样不需要连续的内存可可选择的固定大小外, 还可以选择不识闲垃圾收集, 相对而言, 垃圾收集行为在这边区域是比较少出现的.
在方法区会报出 永久代内存溢出的错误. 而 java1.8 为了解决这个问题, 就提出了 meta space(元空间) 的概念, 就是为了解决永久代内存溢出的情况, 一般来说, 在不指定 meta space 大小的情况下, 虚拟机方法区内存大小就是宿主主机的内存大小
程序计数器
程序计数器是一块较小的内存空间, 他可以看做是当前线程所执行字节码的行号指示器. 在虚拟机的概念模型里, 字节码解释器工作时就是通过改变这个计数器的值来选择下一条将要执行的字节码指令.
由于 JAVA 虚拟机的多线程是通过多线程流转切换并分配处理器执行时间的方式来实现的. 在任一一个确定的时刻, 一个处理器都只会执行一条线程中的指令. 因此, 为了线程切换后能恢复到正确的执行位置, 每条线程都需要一个独立的程序计数器, 各个线程的计数器之间互不影响, 独立存储, 我们称该类内存区域为线程私有
如果线程正在执行一个 Java 方法, 这个计数器记录的是正在执行的虚拟机字节码指令的地址.
运行时常量池
运行时常量池是方法区的一部分. Class 文件除了 有类的版本, 字段, 方法, 接口等描述信息外, 还有一项是常量池, 用于存放编译期生成的各种字面量和符号引用, 这部分内容在类加载后进入方法区的运行时常量池.
运行时常量池相对于 Class 文件常量池的另外一个重要特征是具备动态性. Java 语言并不要求常量一定只有在编译器才能产生, 依旧是并非预置入 Class 文件中的常量池的内容才能进入方法区运行时常量池
来源: https://www.cnblogs.com/KevinStark/p/10925666.html