摘要: 本模块分为四个部分讲解, 分别为 (1) 内存空间;(2)内存分配;(3)内存回收 [重点] ;(4) 内存状况分析.
内存空间:
内存空间是指我们在运行 Java 程序时, Java 源文件通过编译器产生字节码文件在 JVM 中的运行与存储情况.
内存空间从线程是否共享分为:
线程私有:
1)程序计数器
一块较小的空间, 是当前线程所执行的字节码行号指示器, 每条线程都有自己的程序计数器, 因此它也被称为 "线程私有" 内存.
2)虚拟机栈
是描述 Java 方法执行的内存模型, 每个方法在执行的同时都会创建一个栈帧 (Stack Frame) 用于存储局部变量表, 操作数栈, 动态链接, 方法出口等信息. 每个方法从调用到执行完成, 就对应着一个栈帧在虚拟机栈中入栈到出栈的过程.
栈帧: 是用来存储数据和部分过程结果的数据结构, 同时也被用来处理动态链接, 方法返回值和异常分派. 栈帧随着方法的调用而创建随着方法结束而销毁 -- 无论方法是正常完成还是 (抛出了在方法内未被捕获的异常) 都算作方法结束.
3)本地方法栈
本地方法区和 Java Stack 作用相似, 区别是虚拟机栈为执行 Java 方法服务, 而本地方法栈则为 Native 方法服务, 如果一个 VM 实现使用 C-linkage 模型来支持 Native 调用, 那么栈将会是一个 C 栈, 但 HopSpot VM 直接就将本地方法栈和虚拟机栈合二为一.
线程共享:
4)方法区 / 永久代
我们常说的永久代, 用于存储被 JVM 加载的类信息, 常量, 静态变量, 即时编译器编译后的代码等数据. HotSpotVM 把 GC 分代收集扩展至方法区, 即使用 Java 堆的永久代来实现方法区, 这样 HopSpot 的垃圾收集器就可以像管理 Java 堆一样管理这一部分内存, 而不必为方法区专门开发内存管理器.
运行时常量池是方法区的一部分. class 文件除了有类的版本, 字段, 方法, 接口等描述信息外, 还有一项信息是常量池, 用于存放编译器生成的各种字面量和符号引用, 这部分内容在类加载后存放到方法区的运行常量池中.
5)类实例区(Java 堆)-- 运行时数据区
是被线程共享的一块区域, 创建的对象和数组都保存在 Java 堆内存中, 也是垃圾收集的最重要的内存区域. 由于现代 VM 采用分代收集算法, 因此 Java 堆从 GC 角度还可以细分为: 新生代 (Eden 区, From Survivor 区和 To Survivor 区) 和老年区.
直接内存: 不受 JVM GC 管理
来源: http://www.bubuko.com/infodetail-3457080.html