1:JVM内存结构分类
1.1:线程共享区 堆 方法区 1.2:线程独占区 程序计数器 java虚拟机栈 本地方法栈
2:程序计数器
程序计数器是一块较小的内存空间。它可以看作是“当前线程所执行的字节码的行号指示器”。
线程独占。
如果是java方法,这个程序计数器记录的是“正在执行的虚拟机字节码指令的地址”。如果执行的是native方法,这个程序计数器的值为undefined。
3:java虚拟机栈
3.1:虚拟机栈描述的是“java方法执行的动态内存模型”。 3.2:栈帧 每个方法执行,都会创建一个栈帧,伴随着方法从创建到执行完成。用于存储“局部变量表,操作数栈,动态链接,方法出口”等。 后进先出 3.3:局部变量表 存放编译器可知的各种基本试数据类型,引用类型,returnAddress类型。 3.4:大小
4:本地方法栈
虚拟机栈为虚拟机执行java方法服务
本地方法栈为虚拟机执行native方法服务
5:堆
存储对象的实例
垃圾收集器管理的主要区域
新生代,老生代,Eden空间(分区域是为了垃圾收集)
-Xms -Xmx
6:方法区
储存虚拟机加载的类信息(类的版本,字段,方法,接口),常量,静态变量,即时编译器编译后的代码等数据 方法区被称为永久代 垃圾回收在方法区的行为 对这块区域进行垃圾回收的主要目标是对常量池的回收和对类的卸载,但是一般比较难实现。 HotSpot 虚拟机把它当成永久代来进行垃圾回收。但是很难确定永久代的大小,因为它受到很多因素影响,并且每次 Full GC 之后永久代的大小都会改变,所以经常会抛出 OutOfMemoryError 异常。
为了更容易管理方法区,从 JDK 1.8 开始,移除永久代,并把方法区移至元空间,它位于本地内存中,而不是虚拟机内存中。 异常的定义
7:运行时常量池
运行时常量池属于方法区 String a="abc"; String b="abc"; String c="abc"; String c=new String("abc); c.intern(); //将堆中的abc复制到常量池中 a,b的abc先在常量池中创建(相同的只创建一份),通过new创建的字符串,直接在堆中创建,不再放到运行时常量池中
8:直接内存