java中的内存分配
前言 昨天去面试 被问到,我说1.7之后静态变量在堆内存中,面试官很明显的提出了质疑 静态变量在堆中,这个疑问和诧异的表情,下意识的让我感觉我说错了,我随即改口到在方法区,前面我叙述了在1.7之后 方法区被取代改成了元空间,面试当时也忘的差不多了,回来做记录,下面先看1.6 1.7 1.8 内存运行时分配图(感谢划船一哥的图)
在此建议各位面试官,要了解清楚再来面试别人 不要误导
在1.7中 为了逐步去除永久代
将静态变量 和 字符串常量池 放到了堆内存中
在1.8中
去掉了永久代,随着出现的就是MetaSpace元空间,元空间使用的是本地内存,存储类信息,域信息,方法信息,常量池,到ClassLoader的引用 ,和Class对象的引用。字符串常量池和静态白能量仍然存在堆中
1.方法区(又叫静态存储区),元空间
- 编译时就分配好,在程序运行期间都存在,线程共享
- 其主要存储数据,以及实现位置,在1.6及之前,1.7, 1.8均做出了修改
- 在1.6及之前主要存储如下数据
- 类信息
- 域信息
- 方法信息
- 常量池
- 静态常量池:即*.class文件中的常量池
- 运行时常量池:虚拟机会将各个class文件中的常量池载入到运行时常量池中,即编译期间生成的字面量、符号引用,总之就是装载class文件。
- 字符串常量池
- 整型常量池:Integer,类似字符串常量池
- 静态变量(类变量)
- 一个到
classLoader
的引用 - 一个到
class
对象的引用 - 方法表
- 在1.7中 为了逐步去除永久代
- 将静态变量 和 字符串常量池 放到了堆内存中
- 在1.8中
- 去掉了永久代,随着出现的就是
MetaSpace元空间
,元空间使用的是本地内存,存储类信息,域信息,方法信息,常量池,到ClassLoader的引用 ,和Class对象的引用。字符串常量池和静态白能量仍然存在堆中
- 去掉了永久代,随着出现的就是
- 在1.6及之前主要存储如下数据
- 1.6,1.7 1.8 方法区实现位置对比
- 1.7以及1.7之前 方法区依托永久代实现,与堆共享内存
- 1.8 将永久代移除,取而代之的是元空间,元空间使用本地内存
- 为什么将永久代替换为元空间?
- 永久代大小调整困难无法具体确定分配多少空间,而元空间在本地内存中,maxMetaspaceSize默认值为-1表示无穷大,避免oom的出现
- 可以使用 -XX:MaxMetaspaceSize 标志设置最大元空间大小,默认值为 unlimited,这意味着它只受系统内存的限制。
- -XX:MetaspaceSize 调整标志定义元空间的初始大小如果未指定此标志,则 Metaspace 将根据运行时的应用程序需求动态地重新调整大小。
- 永久代大小调整困难无法具体确定分配多少空间,而元空间在本地内存中,maxMetaspaceSize默认值为-1表示无穷大,避免oom的出现
- 为什么将字符串常量池放到了堆内存?
- 字符串常量池在代码中经常被用到,在永久代(方法区)很难被回收,导致永久代空间不足,放到堆中方便GC 对其进行回收操作
- 注
- 个人认为方法区是一段独立的逻辑完成信息存储的工作,去除永久代之后,推出的元空间也是完成类似的操作,所以感觉不能说方法区被移除了,是换了个地方换了个名字
2 .堆区
- 堆
- 存放, 对象的实例 和数组,线程共享,由GC 回收
- 并不是所有对象实例都会存放在堆中
- 1999年提出了逃逸分析并在jdk1.6 实现
- 方法逃逸
- 当一个对象在方法中定义后,它可能被外部方法访问到,比如说通过参数传递到其它方法中
- 线程逃逸
- 当一个对象在方法中定义后,它可能赋值给其它线程中访问的变量
- 如果不满足逃逸分析就会走
栈上分配
- 执行方法频率比较低是不会触发
栈上分配
栈上分配
优势就在于方法结束自动释放无需调用GC
- 执行方法频率比较低是不会触发
- 方法逃逸
- 存放, 对象的实例 和数组,线程共享,由GC 回收
3.栈区
- 本地方法栈
- java程序员不用考虑 该栈是为了提供给非java语言方法的,比如一段java代码调用了C的方法
- Jvm(虚拟机)栈 线程私有 不共享
- 每个线程有一个私有的栈,随着线程的创建而创建。栈里面存着的是一种叫“栈帧”的东西,每个方法会创建一个栈帧,栈帧中存放了局部变量表(基本数据类型和对象引用)
- 当方法执行时,创建基本数据类型变量和,对象的引用会被存在在局部变量表
- 当方法执行结束,自动释放
- 每个线程有一个私有的栈,随着线程的创建而创建。栈里面存着的是一种叫“栈帧”的东西,每个方法会创建一个栈帧,栈帧中存放了局部变量表(基本数据类型和对象引用)
4. 程序计数器
- 用来记录当前线程执行到的代码位置,线程私有不共享