java1.6、1.7、1.8 的内存分配

java中的内存分配

前言 昨天去面试 被问到,我说1.7之后静态变量在堆内存中,面试官很明显的提出了质疑 静态变量在堆中,这个疑问和诧异的表情,下意识的让我感觉我说错了,我随即改口到在方法区,前面我叙述了在1.7之后 方法区被取代改成了元空间,面试当时也忘的差不多了,回来做记录,下面先看1.6 1.7 1.8 内存运行时分配图(感谢划船一哥的图
在此建议各位面试官,要了解清楚再来面试别人 不要误导

JDK6 内存分配
JDK7 内存分配
在1.7中 为了逐步去除永久代
将静态变量 和 字符串常量池 放到了堆内存中
JDK8 内存分配
在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.7 1.8 方法区实现位置对比
    • 1.7以及1.7之前 方法区依托永久代实现,与堆共享内存
    • 1.8 将永久代移除,取而代之的是元空间,元空间使用本地内存
  • 为什么将永久代替换为元空间?
    1. 永久代大小调整困难无法具体确定分配多少空间,而元空间在本地内存中,maxMetaspaceSize默认值为-1表示无穷大,避免oom的出现
      • 可以使用 -XX:MaxMetaspaceSize 标志设置最大元空间大小,默认值为 unlimited,这意味着它只受系统内存的限制。
      • -XX:MetaspaceSize 调整标志定义元空间的初始大小如果未指定此标志,则 Metaspace 将根据运行时的应用程序需求动态地重新调整大小。
  • 为什么将字符串常量池放到了堆内存?
    • 字符串常量池在代码中经常被用到,在永久代(方法区)很难被回收,导致永久代空间不足,放到堆中方便GC 对其进行回收操作
    • 个人认为方法区是一段独立的逻辑完成信息存储的工作,去除永久代之后,推出的元空间也是完成类似的操作,所以感觉不能说方法区被移除了,是换了个地方换了个名字

2 .堆区

    • 存放, 对象的实例 和数组,线程共享,由GC 回收
      • 并不是所有对象实例都会存放在堆中
      • 1999年提出了逃逸分析并在jdk1.6 实现
        • 方法逃逸
          • 当一个对象在方法中定义后,它可能被外部方法访问到,比如说通过参数传递到其它方法中
        • 线程逃逸
          • 当一个对象在方法中定义后,它可能赋值给其它线程中访问的变量
        • 如果不满足逃逸分析就会走栈上分配
          • 执行方法频率比较低是不会触发栈上分配
          • 栈上分配优势就在于方法结束自动释放无需调用GC

3.栈区

  • 本地方法栈
    • java程序员不用考虑 该栈是为了提供给非java语言方法的,比如一段java代码调用了C的方法
  • Jvm(虚拟机)栈 线程私有 不共享
    • 每个线程有一个私有的栈,随着线程的创建而创建。栈里面存着的是一种叫“栈帧”的东西,每个方法会创建一个栈帧,栈帧中存放了局部变量表(基本数据类型和对象引用)
      • 当方法执行时,创建基本数据类型变量和,对象的引用会被存在在局部变量表
      • 当方法执行结束,自动释放

4. 程序计数器

  • 用来记录当前线程执行到的代码位置,线程私有不共享
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值