1.Java虚拟机栈
- java方法执行时的内存模型
1.1 栈帧
- 每个方法都会在虚拟机栈中创建一个对应的栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。
- 一个方法的调用到结束就对应这一个栈帧从虚拟机栈入栈到出栈。
1.2 局部变量表
- 存放编译期可知在方法中各种基本数据类型和对象的引用,基本数据类型直接存值(字面量),引用类型存指向对象的指针或者代表对象的句柄或者与对象位置有关的信息。
1.2.1 double long 型数值会占据2个局部变量空间(slot)其余数据类型只占一个。
1.2.2 局部变量表所需空间在编译期就已经确定下来了,进入一个方法在Java虚拟机栈的栈帧中分配的局部变量表大小是不会在变得。
2.方法区
- 存已经被虚拟机加载的类信息(Class对象)、常量、静态变量、即时编译器JIT编译过后的代码数据。如 a.f() 中a ,f 都是字符常量,都在方法区中。
- jdk 1.7、1.8 对方法区做出了修改,1.8 取消了方法区。
- 1.7开始把方法区中的部分区域移到了其他地方,如字符串常量池移入到堆中。
2.1 方法区被Java虚拟机规范描述为堆的一个逻辑部分,但它不是堆,有一个别名叫非堆Non-Heap
2.2 jdk1.6 及之前方法区位于永久代(PermGen),永久代和堆相互隔离。
2.3 方法区可以不需要连续的内存空间,也可以固定大小,也可以扩展,也可以不实现垃圾收集,如果实现则主要针对常量池的回收和类型的卸载。
2.41.8废弃永久代的原因:由于永久代内存经常不够用或发生内存泄露,爆出异常java.lang.OutOfMemoryErroy。元空间的本质和永久代类似。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。也就是不局限与jvm可以使用系统的内存。理论上取决于32位/64位系统可虚拟的内存大小。