标签:用户线程 链接 异常 pat 调用 行操作 常量池 指示器 依赖
一、JVM内存区域
JVM 内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区域【JAVA 堆、方法区】、直接内存。
线程私有数据区域生命周期与线程相同,依赖用户线程的启动/结束 而 创建/销毁。
程序计数器:
是一块较小的内存空间,是当前线程所执行的字节码的行号指示器。
正在执行java方法的话,计数器记录的是虚拟字节码指令的地址(当前指令的地址)。如果还是native方法,则为空。
这个内存区域是唯一 一个在虚拟机中没有规定任何OutOfMemoryError情况的区域。
虚拟机栈:
是描述java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
栈帧(Frame)是用来存储数据和部分过程结果的数据结构,同时也被用来处理动态链接(Dynamic Linking)、方法返回值和异常分派(Dispatch Exception)。栈帧随着方法调用而创建,随着方法结束而销毁,无论方法是正常完成还是异常完成(抛出了在方法内未被捕获的异常)都算作方法结束。
本地方法栈:
本地方法栈和 Java Stack 作用类似,区别是虚拟机栈为执行 Java 方法服务,而本地方法栈则为Native 方法服务,如果一个 VM 实现使用 C-linkage 模型来支持 Native 调用,那么该栈将会是一个C 栈,但 HotSpot VM 直接就把本地方法栈和虚拟机栈合二为一。
线程共享区域随虚拟机的启动/关闭而创建/销毁。
堆:
是被线程共享的一块区域,创建的对象和数组都保存在Java堆中,也是垃圾收集器进行垃圾收集的最重要的内存区域。由于现代VM采用分代收集算法,因此Java堆从GC的角度还可以细分为:新生代(Eden区、From Survivor区和 To Survivor区)和老年代。
初始化的对象,成员变量(非static的变量),所有对象实例和数组都要在堆上分配。
方法区(永久代):
主要存储类信息,常量池(static常量和static变量),编译后的代码(字节码)等数据。
直接内存并不是JVM运行时数据区的一部分,但也会被频繁的使用:在 JDK 1.4 引入的 NIO 提供了基于 Channel 与 Buffer 的 IO 方式,它可以使用 Native 函数库直接分配堆外内存,然后使用DirectByteBuffer 对象作为这块内存的引用进行操作, 这样就避免了在 Java堆和 Native 堆中来回复制数据,因此在一些场景中可以显著提高性能。
标签:用户线程 链接 异常 pat 调用 行操作 常量池 指示器 依赖
原文地址:https://blog.51cto.com/14298563/2495983