一、Java内存区域
- 线程隔离(独占)的数据区:虚拟机栈、本地方法栈、程序计数器
每个线程都会有它独立的空间,随线程的生命周而创建和销毁 - 所有线程共享的数据区:堆、方法区
所有线程都能访问这块内存数据,随虚拟机或GC而创建和销毁
1、程序计数器
- 程序计数器可以看作是当前线程所执行的字节码的行号指示器。字节码解释器就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。
- 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。
- 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何Out0fMemoryError情况的区域。
2、Java虚拟机栈
- 虚拟机栈是描述Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
- 一般来讲,将Java内存区分为堆内存(Heap)和栈内存(Stack),这里的栈内存一般就是指虚拟机栈,或者虚拟机栈中的局部变量表
3、本地方法栈
- 本地方法栈与虚拟机栈发挥的作用非常相似,只不过,虚拟机栈执行Java方法(即字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务
- Hotspot虚拟机中虚拟机栈与本地方法栈的实现方式一样, 超出大小后也会抛StackOverFlowError
4、Java堆
- Java堆是被所有共享的一块内存区域, 在虚拟机启动时创建
- 存放对象的实例
- 垃圾收集器的主要管理区域
- Java堆还可以细分为: 新生代和老年代, 新生代又可以细分为Eden 空间, From Survivor空间 和To
Survivor空间 - 空间满了会抛OutOfMemoryError
5、方法区
- 方法区是各个线程共享的内存区域
- 用于存储已被虚拟机加载的类信息, 常量,静态变量, 即时编译后的代码等数据
- 虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分, 但它却有一个别名叫Non-Heap, 目的应该是与Java堆区分开来
- Oracle的Hotspot虚拟机在Java7中方法区放在’永久代’(Permanent Generation),
Java8放在元数据空间, 并且通过GC机制对这个区域进行管理 - 运行时常量池是方法区的一部分
二、查看Class文件内容
javac xx.java 编译.java文件,得到对应的字节码.class文件
javap -v xx.java -> xx.txt 可以根据class字节码文件,反解析出当前类对应的code区(汇编指令)、本地变量表、异常表和代码行偏移量映射表、常量池等等信息
示例如下
三、程序运行过程
根据以上-查看class文件内容中的字节码数据查看数据出入栈的过程
来源:CSDN
作者:大栗子122
链接:https://blog.csdn.net/weixin_45095479/article/details/103818583