深入理解java虚拟机笔记(1)java虚拟机内存划分
一、java虚拟机内存划分
1.1.程序计数器
程序计数器是当前线程执行的字节码的行号指示器,字节码解释权通过改变这个计数器的值来选取下一条需要执行的字节码指令。它是程序控制流的指示器,分支、循环、跳转、异常处理,线程恢复都需要依赖这个计数器完成。
每个线程都有一个独立的程序计数器,独立存储、互不影响。
1.2.java虚拟机栈
java虚拟机栈也是线程私有的,它的生命周期与线程相同。
虚拟机栈描述的是java方法执行时的内存模型。每个java方法执行时,java虚拟机都会同步创建一个栈帧,用于存储局部变量表、操作数栈、动态连接、方法出口等信息。
每一个方法从执行到执行结束的过程,就对应一个栈帧从入栈到出栈的过程。
局部变量表存储了编译器可知的各种java虚拟机基本数据类型、对象的引用类型和returnAddress类型(一条字节码指令的地址)。其中long和double会占用两个局部变量槽slot,其他的都占用一个。
如果线程请求的栈深度大于虚拟机运行的深度,就会抛出StackOverflowError ,如果虚拟机栈申请不到足够的内存,就会抛出OutOfMemoryError 。
1.3.本地方法栈
本地方法栈实现原理与虚拟机栈相同,不过是用来专门执行本地方法的。
1.4.java堆
java堆是虚拟机管理的内存中最大的一块。被所有线程共享。在虚拟机启动时创建,用于存放java对象。
java堆是垃圾收集器管理的内存区域。现代虚拟机大部分根据分代收集理论设计,对于堆内存的分配,Java虚拟机都是按照可扩展来实现的(通过参数-Xmx和-Xms设定) 。 如果在Java堆中没有内存完成实例分配, 并且堆也无法再扩展时, Java虚拟机将会抛出OutOfMemoryError异常
1.5.方法区
虽然叫方法区,但这里面存的却不是方法!
方法区域java堆一样,由多个线程共享,它用于存储被java虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。如果方法区无法满足新的内存分配需求时, 将抛出OutOfMemoryError异常。
运行时常量池是方法区的一部分。class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池表,用于存放编译器生成的各种字面量和符号引用。这部分内容在类加载后放在运行时常量池中。
常量池无法再申请到内存时会抛出OutOfMemoryError异常
1.6.直接内存
直接内存(Direct Memory) 并不是虚拟机运行时数据区的一部分, 也不是《Java虚拟机规范》 中定义的内存区域。 但是这部分内存也被频繁地使用,在JDK 1.4中新加入了NIO类, 引入了一种基于通道(Channel) 与缓冲区
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix