标记-清除算法的主要副作用是产生大量不连续内存碎片,导致大对象分配失败、空闲链表管理开销上升、后续gc效率恶化,并可能引发提前full gc或outofmemoryerror。

标记-清除算法最直接、最典型的副作用就是产生大量不连续的内存碎片。
内存碎片导致大对象分配失败
标记-清除只回收被标记的垃圾对象,但不移动存活对象。回收后,空闲内存呈离散分布,中间夹杂着大量存活对象。当程序需要分配一个较大对象(如大数组、缓存块)时,即使总空闲内存足够,也可能找不到一块连续的地址空间满足需求,从而触发 提前 Full GC,甚至抛出 OutOfMemoryError。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
空闲链表管理开销上升
JVM 需维护一个空闲内存块链表来记录所有可用区域的起始地址和大小。碎片越多,链表越长,每次分配内存时都要遍历链表查找合适区块——这显著拖慢对象分配速度,尤其在高并发创建对象场景下更明显。
后续 GC 效率进一步恶化
碎片化加剧后,即使使用其他算法(如复制或整理),也会面临额外负担: • 复制算法需频繁搬运对象以拼凑空间,增加 CPU 和内存带宽压力; • 标记-整理虽能压缩,但移动大量存活对象会延长 STW(Stop-The-World)时间; • 碎片本身还会干扰分代假设(如老年代对象本应长期存活),使 GC 策略失准。
实际表现举例
假设堆中剩余 20MB 空闲,但被拆成 400 个 50KB 的小块:
• 一个需 1MB 连续空间的 byte[1024*1024] 就无法分配;
• JVM 不会自动合并这些小块,只能触发新一轮 GC 来尝试腾出连续空间;
• 若此时老年代已接近饱和,就可能直接 OOM。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










