JAVA是一座围城,Java开发不需要像C、C++开发人员那样,维护每个对象从开始到终结的职责 。因为Java虚拟机会帮助我们完成这些职责,但是一旦发生内存泄漏和溢出,就需要我们排查 。
文章插图
Java虚拟机执行Java程序时,把它管理的整个内存区域称为运行时数据区 。同时根据区域的用途,以及创建和销毁时间等因素,将运行时数据区分成不同的区域 。
文章插图
程序计数器程序计数器表示当前线程所执行字节码指令的行号计数器 。字节码解释器通过改变程序计数器的值,选取下一条需要执行的指令 。为了保证线程切换之后恢复到正确的执行位置,每条线程都需要独立的程序计数器,所以程序计数器是线程私有的 。同时程序计数器是唯一一个在虚拟机规范中没有规定 OutOfMemoryError 的区域 。
注:线程执行Java方法,程序计数器记录字节码指令地址;如果执行的是本地(Native)方法,程序计数器为空 。
文章插图
虚拟机栈虚拟机栈是Java方法执行的线程内存模型 。每个方法的执行,Java虚拟机都会创建一个栈帧存储方法相关变量 。每个方法被调用到执行完毕的过程,对应栈帧在虚拟机栈中入栈到出栈的过程 。
如下图所示,当虚拟机执行 swap(a,b) 方法时,会创建一个单独的栈帧 swap(a,b) 栈帧,在该栈帧中会存储于方法相关的变量,该栈帧的入栈和出栈操作对应着方法的执行和结束 。
文章插图
每个栈帧都包含了局部变量表、操作数、动态链接、方法返回值 。
- 局部变量表:存放方法参数和内部定义的局部变量 。局部变量表的容量以变量槽为最小单位每个变量槽可以存放一个 boolean 、 byte 、 char 、 short 、 int 、 float 、 reference 、 returnAddress 数据类型 。
- 操作数栈:底层也是栈结构,是进行数据运算的地方 。当一个方法刚刚开始执行时,其操作数栈是空的,随着方法执行和字节码指令的执行,会从局部变量表或对象实例的字段中复制常量或变量写入到操作数栈,再随着计算的进行将栈中元素出栈到局部变量表或者返回给方法调用者,也就是出栈/入栈操作 。
- 动态链接:将常量池中指向方法的部分符号引用,在方法运行期间转为直接引用 。字节码中的方法调用指令就是以常量池中指向方法的符号引用作为参数 。这些符号引用一部分会在类加载阶段或第一次使用时转化为直接引用,这种转化称为静态解析 。另一部分将在每一次运行期间转化为直接引用,这部分称为动态连接 。
- 返回地址:方法执行退出后,返回到方法被调用的地方 。
文章插图
在 swap 函数执行的过程中,a 、 b 、 temp 都会保存到局部变量表中,其中的赋值操作则通过操作数栈执行,
方法执行完毕返回到调用的地方的地址则存储在返回地址中 。
文章插图
本地方法栈本地方法栈与 Java 虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则是为虚拟机使用到的 Native 方法 服务 。
Java堆Java堆是虚拟机管理的内存中最大的一块,几乎所有对象都在Java堆分配内存 。Java堆在虚拟机启动的时候创建,被所有的线程共享 。Java堆也会涉及到内存回收的内容,本片文章先不展开了 。Java堆无法扩展时,会报出 OutOfMemoryError 异常 。
文章插图
方法区方法区存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码缓存等数据 。方法区是各个线程共享的内存区域 。
文章插图
屏幕面前的你,会不会遇到这样的困惑 。方法区和永久代有什么关系?和元空间呢?
- 方法区和永久代的关系方法区是JVM规范概念,而永久代则是HotSpot虚拟机特有的概念 。《Java虚拟机规范》只是规定了有方法区的概念和作用,并没有规定如何去实现它 。那么,在不同的 JVM 上方法区的实现肯定是不同的了 。同时大多数用的JVM都是Sun公司的HotSpot 。在HotSpot上把GC分代收集扩展至方法区,或者说使用永久代来实现方法区 。因此永久代是HotSpot的概念,方法区是Java虚拟机规范中的定义,是一种规范,而永久代是一种实现,一个是标准一个是实现 。其他的虚拟机实现并没有永久带这一说法 。在1.7之前在(JDK1.2 ~ JDK6)的实现中,HotSpot 使用永久代实现方法区,HotSpot 使用 GC分代来实现方法区内存回收,可以使用如下参数来调节方法区的大小 。
推荐阅读
- 分享几款Linux 下C/C++程序内存泄漏检查工具
- Java虚拟机工作原理详解
- 12个提高 JavaScript 技能的概念
- Java 实现6种负载均衡算法
- 四个最佳实践,引导你写出高质量JavaScript模块
- Java 字符串格式化 Formatter
- 电脑系统重装GHOST使用图解说明
- 家居风水财位图解
- Java集合详解
- 如何在Java中创建不可变类?