公司网站建设管理意见,点开图片跳到网站怎么做的,wordpress 两个搜索框,系统开发和软件开发Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。这些区域有不同的用途。 文章目录 线程私有的数据区域1. 程序计数器2. Java 虚拟机栈3. 本地方法栈 线程共享的数据区域1. Java 堆2. 方法区3. 运行时常量池4. 直接内存 线程私有的数据区域
… Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。这些区域有不同的用途。 文章目录 线程私有的数据区域1. 程序计数器2. Java 虚拟机栈3. 本地方法栈 线程共享的数据区域1. Java 堆2. 方法区3. 运行时常量池4. 直接内存 线程私有的数据区域
1. 程序计数器
程序计数器是一块较小的内存空间可以看作当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变程序计数器的值选取下一条需要执行的字节码指令分支、循环、跳转、异常处理、线程恢复等功能都需要依赖程序计数器完成。 为了线程切换后能恢复到正确的执行位置每个线程都需要有独立的程序计数器。由于每个线程的程序计数器是独立存储的因此各线程之间的程序计数器互不影响这类内存区域被称为线程私有的内存区域。 程序计数器是唯一不会出现 OutOfMemoryError 的内存区域。
2. Java 虚拟机栈
和程序计数器一样Java 虚拟机栈也是线程私有的它的生命周期与线程相同。 虚拟机栈描述的是 Java 方法执行的内存模型每个方法被执行的时候会创建一个栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息。一个方法被调用直至执行完成的过程对应一个栈帧在虚拟机中从入栈到出栈的过程。 ● 局部变量表主要存放了编译期可知的各种数据类型boolean、byte、char、short、int、float、long、double、对象引用reference 类型它不同于对象本身可能是一个指向对象起始地址的引用指针也可能是指向一个代表对象的句柄或其他与此对象相关的位置。 ● 操作数栈 主要作为方法调用的中转站使用用于存放方法执行过程中产生的中间计算结果。另外计算过程中产生的临时变量也会放在操作数栈中。 ● 动态链接 主要服务一个方法需要调用其他方法的场景。在 Java 源文件被编译成字节码文件时所有的变量和方法引用都作为符号引用Symbilic Reference保存在 Class 文件的常量池里。当一个方法要调用其他方法需要将常量池中指向方法的符号引用转化为其在内存地址中的直接引用。动态链接的作用就是为了将符号引用转换为调用方法的直接引用。
Java 虚拟机栈会出现两种异常。 ● 如果虚拟机栈不可以动态扩展当线程请求的栈深度大于虚拟机所允许的深度时将抛出 StackOverflowError 异常 ● 如果虚拟机栈可以动态扩展当无法申请到足够的内存时将抛出 OutOfMemoryError 异常。
3. 本地方法栈
本地方法栈和虚拟机栈的作用相似。区别在于虚拟机栈为虚拟机执行 Java 方法服务本地方法栈为虚拟机使用到的本地方法服务(Native)。有的虚拟机如 HotSpot 虚拟机把本地方法栈和虚拟机栈合二为一。 本地方法被执行的时候在本地方法栈也会创建一个栈帧用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。 和虚拟机栈一样本地方法栈也会出现 StackOverflowError 和 OutOfMemoryError 两种异常。
线程共享的数据区域
1. Java 堆
对于大多数应用而言Java 堆是 Java 虚拟机管理的内存中最大的一块。Java 堆是被所有线程共享的内存区域其目的是存放对象实例几乎所有的对象实例都在堆中分配内存。 Java 堆是垃圾回收器管理的主要内存因此也称为 GC 堆Garbage Collected Heap。从垃圾回收的角度由于现代编译器基本都采用分代垃圾回收算法所以 Java 堆还可以分成新生代和老年代新生代又可以细分成 Eden 区、From Survivor 区、To Survivor 区等。细分成多个空间的目的是更好地回收内存或者更快地分配内存。
2. 方法区
和 Java 堆一样方法区也是被所有线程共享的内存区域。方法区用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 当方法区无法满足内存分配需求时将抛出 OutOfMemoryError 异常。 JDK 1.8 将方法区彻底移除取而代之的是元空间元空间使用的是直接内存。
3. 运行时常量池
运行时常量池是方法区的一部分。Class 文件中除了有类的版本、字段、方法、接口等描述信息外还有常量池信息用于存放编译器生成的字面量和符号引用这些信息将在类加载后存放到方法区的运行时常量池中。 运行时常量池也受到方法区内存的限制当常量池无法再申请到内存时将抛出 OutOfMemoryError 异常。
4. 直接内存
直接内存不是虚拟机运行时数据区域的一部分也不是虚拟机规范中定义的内存区域但是这部分也被频繁地使用而且也可能导致 OutOfMemoryError 异常出现。
本机直接内存的分配不受到 Java 堆大小的限制但是直接内存仍然受到本机总内存地大小及处理器寻址空间的限制。如果各个内存区域的总和大于物理内存限制就会导致动态扩展时出现 OutOfMemoryError 异常。