<
JVM摘抄第二节
>
上一篇

JVM摘抄第三节
下一篇

JVM摘抄第一节

内存分配和垃圾回收


JVM运行时内存结构

Sample Pic

其中一些内存区的生命周期与JVM的周期保持一致,而另一部分则是和线程的生命周期保持一致

线程共享内存区

JVM的内存区可以根据受访权限的不同定义为线程共享线程私有两大类。所谓线程共享就是可以被所有的线程共享访问的一类内存区,它包括堆区方法区运行时常量池三个。

Java堆区

1.Java堆区在JVM启动的时候被创建,并且它在实际的内存空间中可以是不连续的

2.Java堆区用来存储对象实例,同时也是垃圾收集器(GC)执行的重点区域。

3.存储在JVM中的java对象可以被分为两大类:生命周期较短的瞬时对象和生命周期非常长的持久对象,在极端的情况下持久对象的生命周期可以和JVM的生命周期相媲美,故分代收集由此产生 Sample Pic

并且堆区在JVM在启动时就已经设定好了大小

方法区

1.同样允许被多个线程共享访问,他存储每一个java类的结构信息:运行时常量池字段方法数据构造函数和普通方法的字节码内容以及类、实例、接口初始化时需要用到的特殊方法等数据

2.在HotSpot中方法去只是逻辑上的独立实际上还是在Java堆区内,方法区物理上也是堆区的一部分

3.方法区在JVM启动时被创建,并且它的大小也是可以不连续的

4.方法区被称为永久代,因为其不会像堆区那样被频繁的进行垃圾回收,但并不代表它不会被回收。如果没有显式的要求对方法区进行内存回收,那么垃圾收集器则只会对方法区中的常量池类型卸载进行回收。

5.方法区同样存在内存溢出的问题。

运行时常量池

1.运行时常量池是方法区的一部分,一个有效的字节码 文件中除了包含类的版本信息、字段、方法以及接口等描述之外,还包含一项信息,那就是常量池表

2.当类加载器成功将一个类或接口加载进JVM之后,就会创建与之对应的运行时常量池,运行时常量池也会有溢出的时候

线程私有区

它是不允许被所有线程共享访问的。线程私有区只允许所述的独立线程进行访问的一类内存区,它包括PC寄存器Java栈本地方法栈三个内存区。

PC寄存器

1.它是线程私有的,生命周期和线程的生命周期保持一致。

2.如果当前线程所执行的方法是一个java方法,那么PC寄存器就会存储正在执行的字节码指令地址。反之如果是native方法,这时PC寄存器的值就是空

3.PC寄存器是JVM中唯一一个没有被明确规定抛出OutOfMemoryError异常的运行时内存区。

Java栈

1.生命周期与线程的生命周期保持一致。

2.Java栈用于存储栈帧,而栈帧用于存储的就是局部变量表操作数栈以及方法出口等信息。

3.Java栈中的局部变量表用存储各类原始数据类型对象引用以及returnAddress类型。returnAddress类型是虚拟机内部的原始数据类型,该类型表示一条字节码指令的操作码。

4.Java栈被允许实现为固定大小的内存或是可以动态扩展的内存大小。

本地方法栈

用于支持本地方法的运行,和Java栈作用类似。

性能监视区

它就是JVM的一块内存共享区,专供外部程序访问这块区域的PerData(性能监控数据),以此来实现外部程序监控JVM的性能循环,但规范中并没有要求一定要实现内存监控区

Top
Foot