最近利用工作之余学习研究了一下java的内存管理机制,在这里记录总结一下。
运行时数据区主要有五个区,分别是 <强> 堆,方法区,虚拟机栈,本地方法栈,程序计数器 >强 、下面我来一一详细讲解这五个数据区
堆
java堆是java虚拟机管理内存中最大的一块,它是被所有线程共享的一块内存区域,在虚拟机启动时创建, <强> 此内存的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在堆分配内存 >强 。
java虚拟机规定,java堆可以处于物理上不连续的内存空间中,只要逻辑上连续即可。在实现时,既可以实现固定大小的,也可以是扩展的,可以 <强> 通过配置- xmx和xms来扩展大小 >强 。如果堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出 <强> OutOfMemoryError >强
方法区
方法区也是被所有线程共享的一块内存区域,在Java虚拟机规范中,方法区是堆的逻辑组成部分,但他又被与堆区分开来,别名称为短命,它主要的存储内容有下面几点
-
<李>
类型的完整有效名
李>
<李>
类型直接父类的完整有效名
李>
<李>
类型的修饰符(公共、抽象,最终的某个子集)
李>
<李>
类型的常量池
李>
<李>
域(领域)信息
李>
<李>
方法(方法)信息
李>
<李>
除了常量外的所有静态(静态)变量
李>
<强> 总结起来就是主要用于存储已被虚拟机加载的类信息,常量、静态变量,编译器编译后的代码等数据 >强
这里我在介绍一下常量池,域信息和方法信息
<编辑id=氨嗉? ——常量池 编辑>
常量池也称为运行时常量池(运行时常量池),用于存放编译期生成的各种字面量和符号引用,它是这个类型用到的常量的一个有序集合,包括
<强>
实际的常量(字符串、整数和浮点常量)和类型、域和方法的符号引用
>强
。
池中的数据项像数组项一样,是通过索引访问的。因为常量池存储了一个类类型所使用到的所有类型、域和方法的符号引用,所以它在java程序的动态链接中起了核心的作用
<编辑id="编辑——领域——”>
——域(领域)信息
编辑>
域的相关信息包括: <强> 域名;域类型;域修饰符(公有、私有、保护、静态、最终稳定,瞬态的某个子集) >强
<编辑id="编辑——方法——“> ——方法(方法)信息 编辑>方法的相关信息包括: <强> 方法名,方法的返回类型(或真空),方法参数的数量和类型(有序的),方法的修饰符(公有、私有、保护,静态的,最后,同步,本地人,抽象的一个子集) >强 ,除了抽象和本地方法外,其他方法还有保存方法的 <强> 字节码(字节码)操作数栈和方法栈帧的局部变量区的大小 >强 。
java虚拟机规范对方法区的限制比较宽松,除了和java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不是实现垃圾收集。垃圾收集行为在方法区也比较少出现,当方法区无法满足内存分配时,会抛出 <强> OutOfMemoryError >强
虚拟机栈
虚拟机栈是线程私有的,它的生命周期与线程相同,当我们开始一个线程时,jvm会为当前线程开辟一块虚拟机栈,当当前线程死亡时,线程的虚拟机栈也会销毁。