文章目录
程序计数器
特点
: 每一个线程都有的,占用的内存很小,运行的速度十分快,没有内存溢出的风险。
作用
: 程序中有多个线程,每一个线程都会抽取一定的时间片来运行,该时间片运行结束就由其他线程来继续运行,每个线程都有一个程序计数器,它就用来当线程运行结束时指向结束位置所指向的字节码运行到的位置,当下一个时间段该线程继续运行时可以在原本的字节码位置继续走下去。当程序中有 while
循环,
for
循环,
switch
,
if
等语句时可以一步一步指向运行时的下一个位置。
异常
: 没有异常。
Java 虚拟机栈
特点
: 每个线程都有栈,栈的空间在编译的时候已经确定好了。
栈针
: 虚拟机栈是由栈针为单位组成的,当方法执行的时候就入栈,当方法执行结束的时候就出栈。
异常
: Stack Overflow 异常是由于,方法过多导致栈针数超过了栈所能承受最大容量导致的,用 xss
可以设置栈深度的大小。Out of memerry,有的虚拟机中的虚拟机栈是动态可扩展的,所以及时方法再多也不会发生 Stack Overflow
,而是会由于方法过多扩展内存,超过了系统最大内存的容量导致 Out of memerry
。Out of memerry 异常是由于系统内存不够,当编译时为栈分配内存的时候无法为栈分配对应的内存导致的。
局部变量表
特点: 每一个栈针都有局部变量表。
存储内容
: 存当前的方法中的基本数据类型,还有符号引用(reference,指向具体的方法实例和类变量)。
存储: 一个 slot
占用
32
位的空间,存储一般类型的数据,当类型为
long
、
double
时需要用两个 slot
单位来存储。局部变量表的大小(也就是
slot
的个数,每个
slot
的容量不同的系统对应不同的值这个没有办法确定)在编译的时候已经确定好的。
本地方法栈
特点
: 同虚拟机栈,存的是本地方法的内容,具体的结构因为没有强行的规定,由各自的虚拟机自行实现。
异常
: 同虚拟机栈 。
堆
特点: 多个线程共有的,内存是动态分配的,主要存储对象实例和数组。堆的内存按照垃圾收集的方式划分分为新生代(eden 区,
suvivor
区),老年代。按照线程方式分,每一个线程都有对应的一个私有的堆内存。
异常: Out of memerry 异常,一直创建新的对象,堆内存不够就动态扩展,直到系统内存也装不下就会报异常。
方法区
特点: 所有栈共享的,内存动态分配的。
存储内容: 类信息,静态变量,常量,class
中缓存的数据。
内存: jdk8 之前用永久代实现的方法区,目的是不用写单独的内存管理方法,直接用堆的垃圾回收就好了,容易发生内存溢出,jdk7 的时候把常量池,静态变量从永久代移动到 了堆区,jdk8 之后用元空间实现的方法区,内存由系统的直接内存提供,不在容易发生内存溢出。
垃圾收集: 方法区一般不进行垃圾回收的,因为卸载一个类需要十分严格的要求。
异常: Out of memerry 异常,方法区一直存类变量等数据,当超过了方法区原本设定的范围就会动态扩展,找到系统内存也装不下就会报异常。
常量池
特点: 是方法区的一部分。
存储内容: 存编译时的数据:class
中的各种字段、符号引用、和符号引用转化的直接引用。运行时的数据:指的是 string
的
intern
方法。
异常: 见常量池异常。
直接内存
存的是
io
流缓冲区,不是运行时数据区的一部分。是由直接内存使用
native
变量进行内存分配的,由堆区中的 DirectByteBuffer
变量操纵,因为要经常和堆进行数据交换,DirectByteBuffer
就很好的解决了这方面的开销
异常
: Out of memerry 异常:由于分配内存的时候系统内存都用来划分堆内存和方法区内存,总是忽略直接内存的内存分配情况,导致直接内存太小发生异常。