杠精派
派聪明
0/512

热门评论

计算机魔术师 2026年06月08日 11:21
引用原文:方法区并不真实存在,属于 Java 虚拟机规范中的一个逻辑概念,用于存储已被 JVM 加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等。
@派聪明 到底存在哪呢?
点赞
回复1 取消回复
派聪明 2026年06月08日 11:22
根据提供的参考资料,方法区在物理内存中的具体存在位置取决于你使用的 JDK 版本: 1. **在 JDK1.7 及更早的版本中**:方法区的具体实现是**永久代**。它直接使用的是 JVM 进程所分配的内存。 2. **在 JDK1.8 及之后的版本中**:方法区的实现被**元空间**所替代。元空间**不再使用 JVM 的内存,而是直接使用本地内存(即操作系统的物理内存)**。同时,运行时常量池和类常量池等也移动到了元空间中(部分如字符串常量池在 JDK1.7 时就已移动到了堆中)。 所以,“方法区并不真实存在”是指它在 JVM规范中只是一个逻辑概念,HotSpot虚拟机在具体落地这个概念时,早期把它放在了 JVM 的“永久代”里,后来把它移到了操作系统的“本地内存(元空间)”里。
点赞
回复 取消回复

8 条评论

嘿嘿 2026年08月31日 21:45
引用原文:你提到了remark,那它remark具体是怎么执行的?三色标记法?
@派聪明 remark是什么
点赞
回复1 取消回复
派聪明 2026年08月31日 21:45
# Remark(重新标记)是什么**Remark 是 CMS垃圾收集器垃圾回收四阶段中的第三个阶段**,作用是修正并发标记期间因业务线程继续运行而导致的标记不准确问题。 ## CMS 的四个阶段1. **初始标记**(STW,很短):只标记 GC Roots 直接可达的对象2. **并发标记**:GC线程与业务线程并发执行,遍历整个对象图3. **重新标记**(STW,较短)⬅️ 就是它4. **并发清除**:清理未标记的对象## 为什么需要 Remark? 并发标记阶段业务线程还在运行,可能修改对象引用关系,导致部分存活对象被漏标。如果不修正,存活对象会被误当作垃圾回收,造成严重错误。 ## Remark具体怎么执行? 结合**三色标记法**(白色=未访问、灰色=访问到但引用未处理完、黑色=完全处理完): 1. **处理写屏障记录的引用变化**:并发标记期间,业务线程更新引用时(如黑色对象新增了对白色对象的引用),写屏障会记录这些变化,Remark阶段统一处理,防止漏标2. **扫描灰色对象**:再次遍历灰色对象,将其引用的对象正确标记3. **完成标记**:处理后灰色对象变黑色,最终所有存活对象都是黑色,白色对象(垃圾)保持不变简言之:Remark =短暂停顿 +借助写屏障修正并发标记的遗漏,保证回收准确性。
点赞
回复 取消回复
嘿嘿 2026年08月31日 21:29
引用原文:标记-复制算法
@派聪明 这是两种算法吧
点赞
回复1 取消回复
派聪明 2026年08月31日 21:29
是的,你观察得很准确!“标记-复制”实际上是两种算法思想的结合,可以拆开理解: ##标记 +复制**标记阶段(Mark)**: - 从 GC Roots 出发,遍历对象引用链-标记所有存活的对象**复制阶段(Copy)**: - 将存活的对象复制到另一块内存空间-然后一次性清空原来整块内存##工作原理标记-复制算法将内存空间划分为两块(或按 Eden:Survivor比例划分),每次只使用其中一块: 1. 内存用完后,**标记**出存活对象2. 把存活对象**复制**到另一块空白区域3. 直接清掉整个旧区域## 特点-✅优点:不会产生内存碎片(因为存活对象被复制后是紧凑排列的) -❌缺点:浪费内存空间(总有一块区域处于空闲状态) - 适用场景:新生代,因为新生代对象存活率低,需要复制的对象少,效率高所以“标记-复制”这个名字本身就说明了它分两步走:先“标记”谁是活的,再“复制”到新地方。它是针对**标记-清除算法会产生内存碎片**这一缺点改进而来的。
点赞
回复 取消回复
嘿嘿 2026年08月31日 21:27
引用原文:,会触发 Major GC,对整个堆进行垃圾回收。
@派聪明 minor gc是回收这个是什么
点赞
回复1 取消回复
派聪明 2026年08月31日 21:28
这句话的上下文是在讲对象晋升老年代后内存不足时会触发 Major GC。简单区分一下: **Minor GC(又称 Young GC)** - 回收区域:**新生代**(Eden 区 +两个 Survivor 区) -触发时机:Eden 区空间不足时- 特点:新生代对象大多朝生夕死,采用标记-复制算法,回收速度快、停顿时间短**Major GC(又称 Old GC)** - 回收区域:**老年代**(原文说“对整个堆进行垃圾回收”,是因为老年代空间不足往往会连带触发针对整个堆的 Full GC) -触发时机:老年代空间不足时,如晋升对象过多、大对象直接分配、内存泄漏等- 特点:停顿时间长,对性能影响较大补充一点:还有一个 **Full GC**,是回收整个 Java堆和方法区的最彻底回收,最耗时。日常开发调优中,重点就是避免频繁的 Full GC。 原文的意思就是:对象在新生代经历多次 GC存活后进入老年代,当老年代内存不足时,就会触发 Major GC / Full GC 来清理。
点赞
回复 取消回复
计算机魔术师 2026年06月08日 11:21
引用原文:方法区并不真实存在,属于 Java 虚拟机规范中的一个逻辑概念,用于存储已被 JVM 加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等。
@派聪明 到底存在哪呢?
点赞
回复1 取消回复
派聪明 2026年06月08日 11:22
根据提供的参考资料,方法区在物理内存中的具体存在位置取决于你使用的 JDK 版本: 1. **在 JDK1.7 及更早的版本中**:方法区的具体实现是**永久代**。它直接使用的是 JVM 进程所分配的内存。 2. **在 JDK1.8 及之后的版本中**:方法区的实现被**元空间**所替代。元空间**不再使用 JVM 的内存,而是直接使用本地内存(即操作系统的物理内存)**。同时,运行时常量池和类常量池等也移动到了元空间中(部分如字符串常量池在 JDK1.7 时就已移动到了堆中)。 所以,“方法区并不真实存在”是指它在 JVM规范中只是一个逻辑概念,HotSpot虚拟机在具体落地这个概念时,早期把它放在了 JVM 的“永久代”里,后来把它移到了操作系统的“本地内存(元空间)”里。
点赞
回复 取消回复

目录