1. 内存结构
1.1 程序计数器
- 定义:Program Counter Register 程序计数器(寄存器)
- 作用:是记住下一条jvm指令的执行地址
- 特点:
- 是线程私有的
- 不会存在内存溢出
1.2 虚拟机栈
- 定义:Java Virtual Machine Stacks (Java 虚拟机栈)
- 作用:为线程运行方法提供内存
- 特点:
- 每次方法的调用都会入栈,执行完方法就会出栈
- 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法,一个方法对应一个栈帧
- 每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存
- 是线程私有的
- 存在内存溢出
- 栈帧过多导致栈内存溢出
- 栈帧过大导致栈内存溢出 问题辨析
-
- 垃圾回收是否涉及栈内存? 答:垃圾回收回时的是堆里面的东西。
-
- 栈内存分配越大越好吗? 答:不是,栈内存越大只会让方法递归得更加深入,但是不会增加运行速度。
-
- 方法内的局部变量是否线程安全? 答:如果方法内局部变量没有逃离方法的作用访问,它是线程安全的,因为它是线程私有的,其他线程访问不到就不存在线程安全问题。如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全。
栈:先入先出
1.3 本地方法栈
- 定义:Native Method Stacks(本地方法栈)
- 作用:与虚拟机栈所发挥的作用是非常相似的,区别只是为虚拟机使用到的本地(Native)服务的。 方法服务
1.4 堆
- 定义:Java Heap 程序计数器(Java堆)
- 作用:所有的对象实例以及数组都在堆上分配
- 特点:
- 它是线程共享的,堆中对象都需要考虑线程安全的问题
- 有垃圾回收机制
- 虚拟机所管理的内存中最大的一块
1.5 方法区
-
定义:Method Area(方法区)
-
作用:用于存储已被虚拟机加载的类信息、常量、静态变量
-
特点:
- 存在内存溢出
- 线程共享
永久代:指的是JDK 8之前,使用永久代来实现方法区,从JDK 8开始使用本地内存(操作系统内存)中实现的元空间来替代了它,StringTable移动到了堆中。
官方定义: It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods used in class and instance initialization and interface initialization.The method area is created on virtual machine start-up. Although the method area is logically part of the heap