jvm:线程程序私有区域与程序共享区域详解

私有:程序计数器、java虚拟机栈、本地方法栈

  1. 程序计数器:当前线程所执行的字节码行号指示器。通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
  2. 虚拟机栈:虚拟机栈描述的是Java方法执行的内存模型 : 每个方法执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

 每一个方法从调用直至执行完成的过程,就对应一个栈帧在虚拟机栈中入栈和出栈 的过程。

生命周期与线程相同:在创建线程时同时创建此线程的虚拟机栈,线程执行结束,虚拟机栈与线程一同被回收。

此区域一共会产生以下两种异常:

如果线程请求的栈深度大于虚拟机所允许的深度(-Xss设置栈容量),将会抛出StackOverFlowError异常。

虚拟机在动态扩展时无法申请到足够的内存,会抛出OOM(OutOfMemoryError)异常

     3.本地方法栈:本地方法栈与虚拟机栈的作用完全一样,他俩的区别是本地方法栈为虚拟机使用的Native方法服务.虚拟机栈为java方法服务,HotSpot JVM中,二者是一块区域

共享:java堆:方法区;运行时常量池

  1. Java堆:jvm启动时创建,存放对象实例,Java堆(Java Heap)是JVM所管理的大内存区域。Java堆是所有线程共享的一块区域,在JVM启动时创建。此内存区域存放的都是对象实例。  

jVM规范中说到:“所有的对象实例以及数组都要在堆上分配”。

Java堆是垃圾回收器管理的最主要的内存区域;且Java堆可以处于物理上不连续的内存空间。

Java堆在主流的虚拟机中都是可扩展的(-Xmx设置大值,-Xms设置小值)。

若在堆中没有足够的内存完成对象实例分配并且堆无法再次扩展时,抛出OOM异常。

OOM:

1)内存溢出:内存中的对象确实还应该存活,但由于内存不够用产生的异常。

2)内存泄漏:对象无法被GC(垃圾对象无法被回收)

2.方法区:永久代(1.8前)mate-space元空间(1.8之后)

包括解析得到的方法、属性、字段、编译器编译后的代码等数据等等。永久带基本不参与垃圾回收

3.运行时常量池:是方法区的一部分,用于存放编译器生成的各种字面量和符号引用

字面量 : 字符串(JDK1.7后移动到堆中) 、final常量、基本数据类型的值。
符号引用 : 类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。

你可能感兴趣的:(java,JVM)