Java面试知识点(五十二)虚拟机 分配内存

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来。分配方式有 “指针碰撞”“空闲列表” 两种,选择那种分配方式由 Java 堆是否规整决定,而 Java 堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

内存分配的两种方式:

  • 指针碰撞
  • 空闲列表

选择以上两种方式中的哪一种,取决于 Java 堆内存是否规整。而 Java 堆内存是否规整,取决于 GC 收集器的算法是 “标记 - 清除”,还是 “标记 - 整理”(也称作 “标记 - 压缩”),值得注意的是,复制算法内存也是规整的

指针碰撞

  1. 适用场合
    堆内存规整,没有内存碎片
  2. 原理
    用过的内存全部整合到一边,没有用过的内存放在另一边,中间有一个分界指针,只需要向着没有用过的内存区域移动对象内存大小位置即可
  3. GC收集器
    Serial、parNew

空闲列表

  1. 适用场合
    堆内存不规整,有内存碎片
  2. 原理
    虚拟机会维护一个列表,该列表会记录那些内存是可用的,在分配的时候找一个足够大的内存区域划分给对象实例,并更新列表
  3. GC收集器
    CMS

内存分配并发问题

在创建对象的时候有一个很重要的问题,就是线程安全,因为在实际开发过程中,创建对象是很频繁的事情,作为虚拟机来说,必须要保证线程是安全的,通常来讲,虚拟机采用两种方式来保证线程安全:

  • CAS + 失败重试: CAS 是乐观锁的一种实现方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。虚拟机采用 CAS 配上失败重试的方式保证更新操作的原子性。
  • TLAB: 为每一个线程预先在 Eden 区分配一块儿内存,JVM 在给线程中的对象分配内存时,首先在 TLAB 分配,当对象大于 TLAB 中的剩余内存或 TLAB 的内存已用尽时,再采用上述的 CAS 进行内存分配
发布了164 篇原创文章 · 获赞 852 · 访问量 29万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 终极编程指南 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览