JVMMemory 怼烎@ 2021-09-11 07:56 146阅读 0赞 /** * java体系 * -----Java程序设计语言 * -----各种硬件平台上的Java虚拟机 * -----class文件格式 * -----JavaAPI类库 * -----第三方Java类库 * * JDK java development kit * ---Java程序设计语言 * ---Java虚拟机 * ---JavaAPI类库 * JRE java runtime environment * --java api类库中的java se api子集 * --java虚拟机 * * java技术体系四个平台 * ----java card 支持java小程序Applets 运行在小内存设备上的平台 * ----java me 支持程序运行在移动终端上的平台,对javaapi精简 * ----Java se支持面向桌面级应用的java * ----java ee支持使用多层架构的企业应用(erp)的java平台 * * * java1.6 Mustang 野马 * 2006年11月13日 javaOne大会 ,宣布java开源 * java1.7 Dolophin 海豚 * * 发展未来 * -----模块化 * -----混合语言 * -----混合语言 表示层用其他语言,中间层使用java python * -----多核并行 * */ /** * Java虚拟机在执行java程序的过程中会把所管理的内存分为若干不同的数据区域 * 运行时数据区 * -----方法区 Method Area * -----虚拟机栈 VM Stack * -----本地方法栈 Native Method Stack * -----堆 Heap * -----程序计数器 Program Couter Register * * 程序技术器 * 是当前线程所执行的字节码的行号指示器 * 字节码解释器工作时是通过改变这个计数器的值来选取下一条需要执行的字节码指令 * * 多线程是通过线程轮流切换并分配处理器执行时间的方式来实现 * 为了线程切换后能恢复到正确的执行位置 * 每条线程都需要有一个独立的程序计数器 * 各条线程之间的计数器互不影响,独立存储,称为这类内存区域为 线程私有 的内存 * * 执行java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址 * 执行Natvie方法,这个计数器值则为空Undefined * 此内存区域是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域 * * * java虚拟机栈 * 是线程私有的,它的生命周期与线程相同 * 虚拟机栈描述的是java方法执行的内存模型 * 每个方法被执行的时候都会创建一个栈帧 Stack Frame 用于存储局部变量表、操作栈、动态、链接、方法出口等 * 每个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程 * * java栈指的就是虚拟机栈,也就是说虚拟机栈中的局部变量表部分 * 局部变量存放了编译期可知的各种基本类型的数据、 * 对象引用(reference类型,它不等同于对象本身,根据不同的虚拟机实现可能是一个对象起始地址的引用指针,或者句柄 * returnAddress类型(指向了一条字节码指令的地址) * * 64位长度的long和double类型的数据会占用2个局部变量空间(slot),其余的数据类型只占用一个 * 局部变量表所需的内存空间在编译期间完成分配 * 当进入一个方法时 * 这个方法需要在帧中分配多大的局部变量空间是完全确定的 * 方法运行期间不会改变局部变量表的大小 * * 虚拟机栈的两种异常 * --线程请求的栈深度大于虚拟机所允许的深度,将会抛出StackOverflowError异常 * --虚拟机栈可以动态扩展,扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常 * * * 本地方法栈 * 与虚拟机栈所发挥的作用是非常相似的 * 虚拟机栈为虚拟机栈执行java方法也就是字节码服务 * 本地方法栈则是为虚拟机使用到的Native方法服务 * 虚拟机规范没有强制规定 * * * Java堆 * java虚拟机所管理的内存中最大的一块 * java堆是被所有线程共享的一块内存区域,在虚拟机启动创建 * 唯一的目的就是存放对象实例 * 随着jit编译器的发展与逃逸分析技术 * 所有对象都分配在堆上不是那么绝对了 * * java堆是垃圾收集器管理的主要区域 * 也称为GC堆 Garbage Collected Heap * 内存回收的角度, * 现在收集器基本都是采用的分代收集算法 * java堆中还可以细分为新生代和老生代 * * 内存分配的角度 * 线程共享的java堆中可能划分出多个线程私有的分配缓冲区Thread Local Allocation Buffer * * java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续 * * * 方法区 * Method Area 和 heap ,是各个线程共享的内存区域 * 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器后的代码等数据 * java虚拟机规范把方法区描述为堆得一个部分,别名NonHeap非堆 * 垃圾回收收集行为在这个区域是较少的出现 * 非数据进入了方法区就永久存在了 * 这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载 * * * 运行时常量池 * Runtime Constant Pool * 是方法区 的一部分 * class文件中除了有类的版本、字段、方法、接口等描述信息, * 常量池Constant Pool Table用于存放编译期生成的各种字面量和符号引用 * 这部分内容将在类加载后存放到方法区的运行时常量池中 * * jvm对class文件的每一部分的格式都有严格的规定 * 但是对运行时常量池没有做任何细节要求 * * 运行时常量池相对于class文件常量池的另一个重要的特征是具备动态性 * 运行期间也可能将新的常量放入池中 * * * 直接内存 * Direct Memory并不是虚拟机运行时数据区的一部分 * 但是使用的频繁 * NIO类,引用了一种基于通道Channel 与缓冲区Buffer的IO方式 * 可以使Native函数库直接分配堆外内存 * 然后通过一个存储在java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作 * 避免在java堆和Native堆中来回复制数据 * * * * 对象访问 * 程序的行为基本上都会涉及java栈、java堆、方法区 * * 指向对象的引用,对象访问方式有 * --使用句柄 * java堆中将会划分出一块内存作为句柄池,引用中存储的就是对象的句柄地址 * 句柄中包含了对象实例数据和类型数据各自的具体地址信息 * --直接指针,不用经过句柄池 * Java堆对象的布局就必须考虑如何放置访问类型数据的相关信息 * reference 中直接存储的就是对象地址 * * * 句柄访问方式reference中存储的是稳定的句柄地址,对象被移动时,只会改变句柄中的实例数据指针,reference本身不需要改变 * * 直接指针访问方式的最大好处就是速度快,节省了一次指针的时间开销 * */ public class sunjava { }
相关 JVMMemory / java体系 -----Java程序设计语言 -----各种硬件平台上的Java虚拟机 -----class文件格式 怼烎@/ 2021年09月11日 07:56/ 0 赞/ 147 阅读
还没有评论,来说两句吧...