- 《码出高效》系列笔记(一):面向对象中的类
- 《码出高效》系列笔记(一):面向对象中的方法
- 《码出高效》系列笔记(一):面向对象中的其他知识点
- 《码出高效》系列笔记(二):代码风格
- 《码出高效》系列笔记(三):异常与日志
- 《码出高效》系列笔记(四):数据结构与集合的框架
- 《码出高效》系列笔记(四):数据结构与集合的数组和泛型
- 《码出高效》系列笔记(四):元素的比较
- 走进JVM之内部布局
- 走进JVM之字节码与类加载
- 走进JVM之GC
内存布局
1.堆(Heap)
存储着所有实例对象,GC的相关详见上一篇
2.元空间(Metaspace)
永久代和元空间都是对方法区的一个实现,方法区是一块所有线程共享的内存区域。Java7及之前为永久代(Perm),之后均为元空间,所以类元信息、字段、静态属性、方法、常量等都移动至元空间。
区别于永久代,元空间在本地内存中分配。
3.虚拟机栈(JVM Stack)
JVM中的虚拟机栈是描述Java方法执行的内存区域,他是线程私有的。栈中的元素用于支持虚拟机方法调用,每个方法从开始调用到执行完成的过程,就是栈帧从入栈到出栈的过程。
通过递归调用可以更好地理解方法的调用,尤其是二叉树的中序遍历,逐级返回有点类似JVM类加载机制的双亲委派模型
局部变量表
存放方法参数和局部变量的区域
- 操作数栈
- 局部变量表
- 常量池引用
操作栈
操作站是一个初始状态为空的桶式结构栈。在方法执行的过程中,会有各种指令往栈中写入和提取信息。
动态连接
每个栈帧包含一个常量池中对当前方法的引用,目的是支持方法调用过程的动态链接。
方法返回地址
- 正常退出,一些关键字
return
等 - 异常退出
只要是退出都会返回到方法被调用的位置。方法退出的过程相当于弹出当前栈帧。
- 返回值压入上层调用栈帧
- 异常信息抛给能够处理的栈帧
- PC计数器指向方法调用后的下一条指令
4.本地方法栈(Native Method Stacks)
线程对象私有,虚拟机栈主内,本地方法栈主外。
线程调用本地方法的时候,会进入一个不再受JVM约束的世界,优点:极高的执行效率、偏底层的跨进程操作;缺点:威胁程序运行的稳定性。
JNI最著名的本地方法:System.currentTImeMillis()
。
5.程序计数寄存器(Program Counter Register)
略
6.小结
从线程共享的角度来看,堆(Heap)和元空间(Metaspace)是线程共享的,其他都是线程内部私有的。