Java程序执行过程:
.java——Java编译器——.class——类加载器加载进内存(运行时数据区)——JVM执行引擎执行
JVM内存管理就是针对运行时数据区进行管理(分配和回收内存空间)
Java内存区域:
1. 方法区
1.1 线程共享
1.2 存放被JVM加载的类信息(版本、字段、方法、接口、常量池)、静态变量、即时编译器编译后的代码
常量池存放:字面量、符号引用(类全限定名、字段和属性、方法和属性)
1.3 无法满足内存分配需求时,抛出OutOfMemoryError异常
2. 堆:JVM启动时创建,内存最大,GC堆
2.1 线程共享
2.2 存放对象实例
2.3 无法满足内存分配需求,堆也无法扩展时,抛出OutOfMemoryError异常
3. 虚拟机栈
3.1 线程私有 周期与线程相同
3.2 存放Java方法,每个方法在执行时创建一个栈帧用于存放局部变量表、操作数栈、动态链接方法、返回值等信息
一个方法的调用到执行完成对应一个栈帧的入栈到出栈
4. 本地方法栈
4.1 线程私有 和JVM的Native方法有关
5. 程序计数器
5.1 线程私有:每条线程都有一个,互不影响,独立存储(多线程中为了切换后恢复到正确执行位置)
5.2 代表当前线程执行的字节码行号指示器(分支、循环、跳转、异常处理、线程恢复)
Java内存模型:
概述:1. JMM是一种抽象概念,并不真实存在,描述的是一组规则或规范(定义了程序中各个变量的访问方式)。
2. JVM运行程序的实体是线程,每个线程创建时JVM都会为其创建一个工作内存(栈空间),用于存储线程私有的数据。所有变量都存储在主内存(线程共享),但线程对变量的操作必须在自己的工作内存中进行,执行流程:
1)首先将变量从主内存拷贝的自己的工作内存
2)对变量进行操作
3)操作完成后将变量写回主内存
Note:A. 不能直接操作主内存中的变量,线程各自的工作内存中存储着主内存中的变量副本拷贝
B. 不同的线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成
C. JMM和Java内存区域的唯一相似点:都存在共享区和私有区。
主内存(线程共享,多条线程对同一个变量进行访问可能存在线程安全问题)对应:方法区和堆区
工作内存(线程私有,不存在线程安全问题)对应:虚拟机栈、本地方法栈和程序计数器