JVM 基础结构
JVM 内部结构如下: 栈, 堆.
栈
JVM 中的栈主要是指线程里面的栈, 里面有方法栈, native 方法栈, PC 寄存器等等; 每个方法栈是由栈帧组成的; 每个栈帧是由局部变量表, 操作数栈等组成.
每个栈帧其实就代表一个方法
堆
java 中所有对象都在堆中分配; 堆中对象又分为年轻代, 老年代等等, 不同代的对象使用不同垃圾回收算法.
-XMs: 启动虚拟机预留的内存
-Xmx: 最大的堆内存
一, 堆的分代假设
根据研究表明, 堆中对象大部分都是创建后, 立马就可以被销毁的. 如:
为了优化堆中的内存, 将堆中对象分为不同代. 在年轻代中, GC 发生比较频繁; 在老年代中, GC 发生比较少.
二, 堆的分代
年轻代: Young Generation
老年代:
Old Generation/Tenured
永久代:
Permanent Generation
永久代在 Java 虚拟机规范中是没有的, 但是 Host Spot 虚拟机中有.
三, 方法区
方法区被所有线程共享; 方法区是用来存储编译后的代码, 即存储每个类的运行时常量池, 字段和方法.
方法区在虚拟机启动时创建; 虽然方法区在逻辑上是堆的一部分, 但在一些简单的实现中, 方法区可以选择不进行垃圾回收和紧凑化.
方法区在 java8 的变化
java7 之前: 方法区的实现: 永久代, 是作为堆的一部分;
java8 之后: 方法区的实现: metaspace, 是堆外的内存;
1, 为什么要这样改变?
因为 java 可以动态加载字节码信息, 这样方法区就会慢慢的挤占堆中内存. 为了避免与堆争抢内存, java8 将方法区的实现移至堆外.
2, 方法区, 永久代, MetaSpace 的区别?
方法区是 java 虚拟机规范所规定的一个概念. 其中 java7 实现方法区的地方称为永久代; java8 实现方法区的地方称为 MetaSpace
字节码文件的结构
java 程序在运行的时候, 将源码编译成字节码, 字节码在不同系统上的 JVM 翻译成对应的机器码. 这是 Java 平台无关性的基础.
但是, 编译后的字节码是如何读取到 JVM 中的? 字节码执行引擎是如何识别, 执行指令?
1, 如何查看字节码文件
classpy 工具
IDEA 的
jclasslib Bytecode viewer
插件
2, 字节码文件结构
一个字节码文件包含以下部分:
- (1)magic:
- 0xCAFEBABE
class 文件的 magic code, 用于标识该文件是 class 文件.
(2)minor_version,major_version
用于标识该 class 文件的版本, 防止高版本的 class 文件被低版本的 JVM 读取并执行.
(3)constant_pool: 常量池
用于存储该 class 文件经常被使用的信息, 优化内存. 比如说 System.out.print()
(4)access_flag
表示这个类得访问权限, 对应到 java 源码就是 public,final 之类的
字节码执行引擎
这里以一个线程为例. 一般来说, 一个方法栈最底层的栈帧都是 Thread.run 方法. 当一个线程准备调用另一个方法时, 会先将实参拷贝一份到新栈帧的局部变量表里, 然后再执行代码.
1, 局部变量表
每次调用新方法时, 会默认将当前对象的地址 this 作为局部变量表的第一个参数; 后面存放传过来的参数. 这与 JavaScript 的做法很相似.
2, 方法调用的相关指令
invokevirtual: 一般实例方法, 有多态;
invokeinterface: 接口方法, 有多态
invokestatuc: 静态方法, 无多态
invokespecial: 特殊方法, 无多态
invokedynamic: 动态调用, JDK7 新增, 方法无需在编译时确定
3, 方法调用的过程
(1) 在开始时
方法栈新增一个栈帧;
实例方法的 this, 参数放到局部变量表中;
开始新栈帧中字节码的执行;
(2) 在返回时
将返回值放在调用者方法栈帧中的操作数栈上;
(3) 在异常出现时
寻找匹配的异常处理代码
(4) 在 finally 时
为每个分支新增一个跳转
4, 为什么 Mockito,EasyMock 无法对 private,static 方法进行 mock?
因为他们 mock 方法是通过覆盖这些方法来实现的, 而 private,static 没法被覆盖. PowerMock 是通过修改字节码文件达到 mock 私有, 静态方法的.
原博客地址 http://wangjie.natappvip.cc/
来源: https://www.cnblogs.com/fourther/p/12673213.html