当前位置: 首页 > news >正文

new对象时,堆会发生抢占吗

答:会

new对象时。指针会向右移动一个对象大小的距离,假如一个线程A正在给字符串对象S分配内存。另外一个线程B同时为ArrayList对象1分配内存,两个线程就发生了抢占。

JVM怎么解决堆内存分配的竞争问题?
为了解决堆内存分配的抢占问题,JVM为每个线程保留了一小块的内存空间,被称为TLAB也就是线程本地分配缓冲区。用于存放该线程分配的对象。

当线程需要分配对象时,直接从TLAB中分配,只有当TLAB用尽或者对象太大需要直接在堆中分配时,才会使用全局分配指针。

这⾥简单测试⼀下 TLAB。

可以通过 java -XX:+PrintFlagsFinal -version | grep TLAB 命令查看当前 JVM 是否开启了 TLAB。

如果开启了 TLAB,会看到类似以下的输出,其中 bool UseTLAB 的值为 true。

我们编写⼀个简单的测试类,创建⼤量对象并强制触发垃圾回收,查看 TLAB 的使⽤情况。

class TLABDemo {public static void main(String[] args) {for (int i = 0; i < 10_000_000; i++) {allocate(); // 创建⼤量对象}		System.gc(); // 强制触发垃圾回收}private static void allocate() {// ⼩对象分配,通常会使⽤ TLABbyte[] bytes = new byte[64];}
}

在 VM 参数中添加 -XX:+UseTLAB -XX:+PrintTLAB -XX:+PrintGCDetails -XX:+PrintGCDateStamps ,运⾏后可以看到这样的内容:

waste:未使⽤的 TLAB 空间。

alloc:分配到 TLAB 的空间。

refills:TLAB 被重新填充的次数。

可以看到,当前线程的 TLAB ⽬标⼤⼩为 10,496 KB( desired_size: 10496KB );未发⽣慢分配( slow allocs: 0 );分配效率直接拉满( alloc: 1.00000 52494KB )。

当使⽤ -XX:-UseTLAB -XX:+PrintGCDetails 关闭 TLAB 时,会看到类似以下的输出:

直接出现了两次 GC,因为没有 TLAB,Eden 区更快被填满,导致年轻代 GC。年轻代 GC 频繁触发,⼀部分⻓⽣命周期对象被晋升到⽼年代,间接导致⽼年代 GC 触发。

相关文章:

  • Docker Volume(存储卷)
  • Netty学习专栏(六):深度解析Netty核心参数——从参数配置到生产级优化
  • SpringBoot3集成Oauth2.1——6数据库存储客户端信息
  • 【数字图像处理】_笔记
  • OpenGAN:基于开放数据生成的开放集识别
  • OceanBase数据库全面解析(高级特性篇)
  • 每日Prompt:黄沙大圣
  • 爱芯元智芯片推理cn-clip
  • 用llama3微调了一个WiFiGPT 用于室内定位
  • 网页模板素材网站 web前端网页制作模板
  • 视频画质等级
  • Spring 核心配置文件(spring.xml)构建指南
  • 蓝桥杯b组c++赛道---数位dp
  • 互联网大厂Java求职面试:AI大模型与云原生架构融合中的挑战
  • Jenkins部署
  • 不打印nacos相关信息,无法进行注册nacos
  • UDP协议原理与Java编程实战:无连接通信的奥秘
  • 企业网络综合实训
  • 七彩喜认知症评估系统:解码大脑健康的“数字先知”
  • 食品检验师的职业发展路径是怎样的?
  • 教人做辐射4mod的网站/代写企业软文
  • 没有网站怎么做外贸/seo任务平台
  • 寺庙招人做网站维护吗/搭建网站的步骤和顺序
  • wordpress主题知言/seo下拉优化
  • 一区适合晚上一个人看b站/含有友情链接的网页
  • 烟台做网站打电话话术/短视频培训机构