JVM内存模型

来源:互联网 发布:国税局王军垃圾知乎 编辑:程序博客网 时间:2024/06/09 19:58

1.程序计数器

一小块内存空间,是当前线程所执行的字节码的行号指示器。字节码解释器就是通过改变该值来选择下一条要执行的字节码指令。分支、循环、跳转、异常处理、线程恢复等基础功能都是依赖该内存完成。

每个线程有自己独立的程序计数器。因为JVM的多线程机制是  通过轮流切换线程并且分配线程执行时间,所以在一个确切的时间点一个处理器(如果是多核,将其看做一个内核)能够执行的命令只有一条。因此每次线程切换后,为了让处理器能恢复到该线程的正确位置,每个线程有自己独立的程序计数器。各线程有独立的程序计数器,互不影响,独立存储,称之为“线程私有”内存。栈 也是线程私有内存。


2.栈

JVM栈描述的是Java方法执行的内存模型,与其对应的线程生命周期相同。线程中每一个方法从被调用到结束,对应着一个栈帧从入栈到出栈。用于存储局部变量表、操作栈、动态链接、方法出口等信息。

(成员变量不管是基本数据类型和引用数据类型都是存在堆里面的,在类创建对象的时候初始化。当该类方法被调用的时候压入栈)

(静态变量存在方法区)

局部变量表存了基本数据类型的局部变量,引用数据类型的引用,以及returnAddress(指向一条字节码指令的地址)。局部变量表的大小在编译期间以及确定,不会改变。


3. 本地方法栈

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java 方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native 方法服务。


4. 堆

所有线程共享的一块内存,是大多数应用的JVM中最大一块,在JVM启动时创建。堆区唯一的作用就是存放实例,几乎所有的对象实例都是在这里分配内存。

根据Java 虚拟机规范的规定,Java 堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样。在实现时,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-Xmx-Xms 控制)。如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError 异常。


5. 方法区

各个线程共享的内存区域,用于存储被已经加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。


6. 运行时常量池

是方法区的一部分。

Class 文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池(Constant PoolTable),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。


0 0
原创粉丝点击