JVM学习笔记17-JVM内存划分

JVM内存划分

  • 虚拟机栈 —Stack Frame,存储方法运行时所需的数据
  • 程序计数器 — Program Counter,记录当前线程所执行的字节码行号
  • 本地方法栈 —主要用于执行本地方法,为JVM所调用到的Native即本地方法服务
  • 堆 — Heap,JVM管理的最大的一块内存空间,存储对象实例
  • 方法区—Method Area,存储运行时的常量池,已被JVM加载的类信息,常量,静态变量,即时编译器编译后的代码等数据
    • 永久代(Permanent Generation)—从JDK1.8开始,已经废弃了永久代,使用元空间(Meta Space)
    • 运行时常量池—方法区的一部分内容,用来存放编译期生成的各种自变量以及符号引用
  • 直接内存—Direct Memory,由OS管理

1虚拟机栈

虚拟机栈描述的是java方法执行的动态内存模型

1.1栈帧-(Stack Frame)

栈帧是一种用于帮助JVM执行方法调用与方法执行的数据结构,每个方法执行都会创建一个栈帧,伴随着方法从创建到执行完成

栈帧本身是一种数据结构,封装如下信息

  • 局部变量表Local Variables
  • 操作数栈Operand Stack
  • 指向当前方法所属的类的运行时常量池的引用Reference to runtime constant pool
  • 方法返回地址Return Address
  • 额外的附加信息

1.2局部变量表

存储编译期可知的各种基本数据类型,引用类型,returnAddress类型

局部变量表的内存空间在编译期完成分配,当进入一个方法时,这个方法需要在帧分配多少内存是固定的,在方法运行期间是不会改变局部变量表的大小


2 程序计数器

  • 是一块较小的内存空间,可以看作是当前线程锁执行的字节码的行号指示器
  • 程序计数器出于线程独占区
  • 此区域是唯一一个在JVM规范没有规定任何OutOfMemoryError情况的区域
  • 如果线程执行的是Java方法,这个计数器记录的就正在执行的虚拟机字节码指令的地址
  • 如果执行的native方法,这只计数器的置为undefined

3 本地方法栈

与虚拟机栈的区别

  • 虚拟机栈为执行java方法服务
  • 本地方法为虚拟机执行native方法服务

4 堆内存

  • 存放对象实例
  • 是Java虚拟机管理内存中最大的一块
  • 垃圾收集器管理的主要区域
  • 现代垃圾收集器都采用了分代收集算法,堆空间也基于这一点进行了响应的划分
    • 新生代
      • Eden空间
      • From Survivor空间
      • To Survivor空间
    • 老生代

相关JVM参数
-Xms3m—设置最小堆内存
-Xmx3m—设置最大堆内存
-XX:+HeapDumpOnOutOfMemoryError—输出内存溢出相关错误信息
-Xss200k—虚拟栈大小JVM参数

在堆中,尤其是在新生代中,常规应用进行一次GC一般可回收70%~95%的空间,而方法区的GC效率远小于次


5 方法区

存储运行时的常量池,已被JVM加载的类信息,常量,静态变量,即时编译器编译后的代码等数据
其中类信息包括

  • 类的版本
  • 字段
  • 方法
  • 接口
  1. 在Java虚拟机规范表示可以不要求虚拟机在该区实现GC—原因是GC性价比较低

5.1 方法区的回收内容

当前的商业JVM都有实现方法区的GC,主要回收两部分内容:

  1. 废弃常量
  2. 无用类

其中

  • 类回收需要满足3个条件
    • 该类所有的实例都已被GC,也就是JVM中不存在改Class的任何实例
    • 加载该类的ClassLoader已经被回收
    • 该类对应的java.lang.Class对象没有在任何地方被引用,如不能在任何地方通过反射访问该类的的方法

在大量通过反射,动态代理,CGLib等字节码框架,动态生成JSP以及OSGi这类频繁自定义ClassLoader的场景都需要JVM具备类卸载的支持以保证方法区不会溢出


6 运行时常量池

方法区的一部分

7 直接内存 Direct Memory

Java NIO密切相关,JVM通过堆上的DirectByteBuffer来操作直接内存


例:

public void method(){
   Object obj = new Objdect();
}
  • 上述代码再运行时生成了2部分的内存区域
    • obj这个引用变量,因为是方法内的变量,放到虚拟机栈(Stack)里面
    • 真正的Object的实例对象,放到堆(Heap)里面
  • 上述的new语句一共消耗了12个bytes,
    • JVM规定
      • 引用占4个bytes(在虚拟机栈Stack)
      • 空对象是8个bytes(在堆内存Heap中)
  • 方法结束后,对应的Stack中的变量马上回收,但是在Heap中的对象要等GC来回收
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值