不可变集合(Immutable)与并发集合(Concurrent)对比:为何前者更省内存?
不可变集合内存占用低于并发集合的原理说明
首先要澄清一个普遍误区:不可变集合修改生成新实例,并不等于会全量复制整个集合的所有数据,其核心依赖持久化数据结构的结构共享特性实现低内存开销:
- 绝大多数工业级实现的不可变集合,修改操作只会复制从根节点到变更节点的路径上的少量节点,剩余未变更的节点会完全和旧版本集合共享,不会重复占用内存。比如大小为100万的不可变红黑树,修改单个元素只会新增约20个节点(对应树的深度log₂(100万)≈20),剩余所有节点都和旧版本复用,新增内存开销可以忽略不计。
- 如果业务场景需要保留多版本集合(比如并发场景下的快照读、历史状态回溯),不可变集合的多版本总内存开销远低于并发集合每次快照需要全量拷贝的成本。
对比并发集合的内存优势具体体现在以下几点:
- 没有同步原语的额外开销:并发集合为了保障线程安全,需要内置锁、CAS状态标记、分段锁冗余结构、避免伪共享的缓存行填充等额外设计,这些基础开销会让同数据量的并发集合,单实例内存占用比不可变集合高30%到2倍不等,比如JDK的
ConcurrentHashMap,空实例的内存占用是不可变HashMap的4倍以上。 - 冗余节点的生命周期更可控:并发集合为了实现弱一致性迭代,通常会标记删除旧节点而不立即回收,冗余节点的留存时间不可控;而不可变集合的旧版本节点只要没有引用指向,就会被GC立即回收,长期运行下内存水位更稳定。
- 无并发修改的预留空间开销:大部分并发集合为了降低扩容时的锁冲突,会预留更高的冗余扩容空间,比如并发哈希表的加载因子通常会设得比普通不可变哈希表更低,空闲槽位的内存浪费更高。
注意:该对比的前提是线程安全的使用场景,如果是单线程场景对比非线程安全的普通可变集合,不可变集合的内存优势并不明显,这里的结论仅针对和并发集合的对比场景。
内容的提问来源于stack exchange,提问作者helpME1986
相关产品推荐
相关产品推荐

