您的位置:首页 > 科技 > 能源 > 重庆网站搭建哪里可以做_湛江疫情最新情况_百度推广费2800元每年都有吗_seo研究中心qq群

重庆网站搭建哪里可以做_湛江疫情最新情况_百度推广费2800元每年都有吗_seo研究中心qq群

2025/4/27 4:47:14 来源:https://blog.csdn.net/xiexf20230814/article/details/147403288  浏览:    关键词:重庆网站搭建哪里可以做_湛江疫情最新情况_百度推广费2800元每年都有吗_seo研究中心qq群
重庆网站搭建哪里可以做_湛江疫情最新情况_百度推广费2800元每年都有吗_seo研究中心qq群
1,JVM调优的目的?

减少STW,也即是减少GC次数,提高程序运行效率。

2,为什么要设计一个STW机制?

这和垃圾回收有关(GC),确保同一时刻系统状态的一致性,防止并发修改导致的不一致性。

 确保操作的一致性
  • 场景:在垃圾回收(GC)、内存压缩或某些系统级操作中,需要冻结整个系统的状态,防止并发修改导致的数据不一致

  • 示例:如果垃圾回收器在标记存活对象时,用户线程同时修改对象引用,可能导致错误回收仍在使用的内存(即“悬挂指针”)。

  • STW的作用:暂停所有线程后,系统可以安全地遍历对象图或执行原子操作,避免中间状态干扰。

3,JVM内存分配策略
1),对象内存分配策略

JVM 主要采用 分代分配(Generational Allocation),优先在新生代(Young Generation)分配,具体策略如下:

  1. 优先在 Eden 区分配

    • 大多数新对象在 Eden 区 分配。

    • 如果 Eden 区空间不足,触发 Minor GC(Young GC)。

  2. 大对象直接进入老年代

    • 如果对象大小超过 -XX:PretenureSizeThreshold(默认 0,由 GC 决定),直接进入 老年代(Old Generation)

    • 避免大对象在 Eden 区频繁复制(如大数组)。

  3. 长期存活对象进入老年代

    • 对象每经历一次 Minor GC,年龄(Age) +1。

    • 当年龄达到 -XX:MaxTenuringThreshold(默认 15),晋升到老年代。

  4. 空间分配担保(Handle Promotion)

    • 如果 Minor GC 后 Survivor 区放不下存活对象,JVM 会检查老年代剩余空间

      • 如果足够,直接进入老年代。

      • 如果不足,触发 Full GC

2),对象动态年龄判断机制

在 Survivor 区(From/To)中,对象的年龄通常由 MaxTenuringThreshold 控制(默认 15)。但 JVM 还采用 动态年龄计算(Dynamic Ageing) 来优化晋升策略:

规则
  • 目标:让 Survivor 区中年龄 1 + 年龄 2 + ... + 年龄 N 的对象总大小 > 50% Survivor 区,则所有年龄 ≥ N 的对象直接晋升老年代。

  • 作用

    • 避免 Survivor 区被长期存活的小对象占满。

    • 减少不必要的复制开销。

总结

对象创建类加载 → 内存分配(指针碰撞/空闲列表)→ 初始化 → 对象头设置 → 构造方法执行
内存分配Eden 优先 → 大对象直接进老年代 → 长期存活晋升老年代 → 空间担保
动态年龄Survivor 区中年龄 1+2+...+N 的对象 >50% 时,年龄 ≥N 的直接晋升

在 JVM 中,**对象内存分配** 是一个高频操作,而多线程环境下,多个线程可能同时申请内存,因此必须保证分配的**线程安全**。JVM 主要通过以下机制确保对象内存分配的线程安全:

---

## **1. 内存分配时的线程安全挑战**
当多个线程同时创建对象时,可能引发以下问题:
1. **内存指针竞争**:多个线程同时移动指针(Bump the Pointer),导致数据覆盖。
2. **空闲列表冲突**:多个线程同时修改空闲列表(Free List),导致内存分配错误。
3. **TLAB 分配失败**:线程本地缓冲区(TLAB)用尽后,回退到全局分配时的竞争。

---

4, JVM 的内存分配线程安全机制

JVM 采用多种策略来保证对象内存分配的线程安全:

(1) TLAB(Thread-Local Allocation Buffer)线程本地分配缓冲区


- **原理**:
  - 每个线程在 **Eden 区** 预先分配一小块私有内存(TLAB),线程优先在自己的 TLAB 中分配对象。
  - 分配时仅需移动线程本地的指针,无需全局同步。
- **优点**:
  - **无锁分配**,减少竞争。
  - 适合小对象的高频分配。
- **缺点**:
  - TLAB 用尽后,仍需全局分配(可能触发同步)。
- **相关参数**:
  - `-XX:+UseTLAB`(默认开启)
  - `-XX:TLABSize`(调整 TLAB 大小)

(2) CAS(Compare-And-Swap)分配


- **适用场景**:
  - 当 TLAB 不足或分配大对象时,回退到 **Eden 区的全局分配**。
  - 使用 **CAS(原子操作)** 更新全局指针(Bump the Pointer)。
- **优点**:
  - 比锁更轻量级。
- **缺点**:
  - CAS 失败时需要重试,可能影响性能。

(3) 锁同步(如 Mutex)


- **适用场景**:
  - 某些垃圾回收器(如 CMS)使用 **空闲列表(Free List)** 管理内存,分配时需加锁。
- **实现方式**:
  - 通过 **pthread_mutex** 或 **JVM 内部锁** 保护空闲列表。
- **缺点**:
  - 锁竞争可能成为瓶颈。

### **(4) 逃逸分析与栈上分配**
- **原理**:
  - 如果 JVM 通过 **逃逸分析(Escape Analysis)** 发现对象**不会逃逸出线程**(即仅被当前线程使用),则直接在 **栈上分配**。
  - 栈是线程私有的,无需同步。
- **优点**:
  - 完全无锁,减少 GC 压力。
- **限制**:
  - 仅适用于**未逃逸的小对象**(默认不开启,需 `-XX:+DoEscapeAnalysis`)。

---

## **3. 不同垃圾回收器的分配策略**
| **GC 收集器**       | **内存分配方式**               | **线程安全机制**                |
|---------------------|------------------------------|-------------------------------|
| **Serial / ParNew** | 指针碰撞(Bump the Pointer)  | TLAB + CAS(全局分配)         |
| **CMS**            | 空闲列表(Free List)         | TLAB + 锁(Free List 修改)    |
| **G1 / ZGC**       | 分区(Region)分配            | TLAB + CAS(全局分配)         |

---

## **4. 优化建议**
1. **减少对象分配频率**:
   - 重用对象(如对象池)。
   - 避免在热点代码中频繁创建小对象。
2. **调整 TLAB 大小**:
   - 如果小对象分配竞争激烈,可增大 TLAB(`-XX:TLABSize`)。
3. **选择合适的 GC**:
   - 低延迟场景用 ZGC/Shenandoah,高吞吐用 G1/Parallel GC。

---

 **总结**
JVM 通过 **TLAB(线程本地缓冲)** + **CAS/锁同步** 的组合策略,在对象内存分配时保证线程安全:
1. **TLAB 优先**:无锁分配,减少竞争。
2. **CAS 回退**:TLAB 不足时,使用原子操作更新全局指针。
3. **锁同步**:某些 GC 使用锁管理空闲列表。
4. **栈上分配**:对未逃逸对象优化,彻底避免同步。

这样既保证了多线程安全,又尽可能减少了锁竞争对性能的影响。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com