Java内存模型

1、jvm内存模型分为几部分

程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区

2、jvm内存模型各个部分

1)程序计数器(线程私有)

定义:程序计数器是一块很小的内存空间,可看作是当前线程所执行字节码的行号指示器,里面记录当前线程正在执行的那一条字节码指令的地址。
注:如果当前线程执行的是本地方法,此时程序计数器为空。

作用:字节码解释器工作时就是通过改变程序计数器的值来选取下一条需要执行的字节码指令。如:循环、顺序执行、异常处理;
多线程的情况下用于记录当前线程执行的位置,从而在线程切换回来的时候知道线程上次执行到哪儿了。

特点:
较小
线程私有
唯一一个不会出现OutOfMemeryError的区域

2)Java 虚拟机栈(线程私有)

定义:Java虚拟机栈是描述java方法运行过程的内存模型;Java虚拟机栈为每一个即将运行的java方法创建一个"栈帧"区域,
这块区域用于存储该方法在运行过程中所需要的一些信息:局部变量表、操作数栈、动态链接、方法出口信息。当方法在运
行过程中需要创建局部变量时,就将局部变量存入栈帧的局部变量表中。

特点:
1、局部变量表是在方法执行的时候随着栈帧的创建而创建,而且局部变量的大小在编译时期就确定下来了,在创建的时候只需要分配
事先规定的大小即可,此外,在方法运行过程中,局部变量表的大小是不会发生变化的。
2、Java虚拟机栈会出现两种异常:StackOverFlowError和OutOfMemoryError。
3、Java虚拟机栈是线程私有的。

注意:
人们常说,Java的内存空间分为“栈”和“堆”,栈中存放局部变量,堆中存放对象。 不完全正确。
真正的Java虚拟机栈是有一个个栈帧组成,每一个栈帧中都拥有:
局部变量表(存放基本数据类型变量、引用类型的变量、returnAddress类型的变量)、操作数栈、动态链接、方法出口信息

3)本地方法栈

本地方法栈和Java虚拟机栈实现的功能类似,只不过本地方法区是本地方法运行的内存模型。在HotSpot虚拟机中和Java虚拟机栈合二为一。

4)Java 堆(线程共享)

定义:堆是用来存储对象的内存空间。

特点:
线程共享
在虚拟机启动时创建
垃圾回收的主要场所
堆的大小既可以固定也可以扩展
分区新生代、老年代

5)方法区(线程共享)

定义:JAVA虚拟机规范中定义方法区是堆的一个逻辑部分,方法区中存放已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。

特点:
线程共享
又称永久代
内存回收效率低
Java虚拟机规范对方法区的要求比较宽松。
永久代在jdk1.8中被移除了,被元空间取代,永久代使用的是JVM的堆内存空间,二元空间使用的是物理内存。

3、哪一个不会出现OutOfMemeryError的区域?

程序计数器

4、年老代在哪个部分?

Java 堆

5、什么是运行时常量池?

运行时常量池是方法区的一部分。用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

6、什么是直接内存?

jvm以外的系统内存

7、直接内存应用实例?

NIO

8、方法区中保存了什么数据?

方法区中存放已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。

9、方法区随着JDK升级的变化情况

java7之前,方法区位于永久代(PermGen),永久代和堆相互隔离,永久代的大小在启动JVM时可以设置一个固定值,不可变;
java7中,长量池从永久代移到堆中;
java8中,取消永久代,方法区存放于元空间(Metaspace),元空间仍然与堆不相连,但与堆共享物理内存,逻辑上可认为在堆中。

你可能感兴趣的:(Java内存模型)