BitSet位图算法如何实现海量数据清洗中的超低内存去重过滤?

2026-04-24 17:220阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计933个文字,预计阅读时间需要4分钟。

BitSet位图算法如何实现海量数据清洗中的超低内存去重过滤?

BitSet 不能直接用于海量数据。

BitSet.set(x) 为什么会 OOM?不是说它省内存吗

省的是有效数据所占的位空间,不是“按需分配”。BitSet 底层是 long[],调用 set(1_000_000_000) 时,它必须确保索引 10⁹ 能被容纳,即至少分配 ⌈10⁹ / 64⌉ ≈ 15.6M 个 long,约 125 MB 连续堆内存。如果最大 ID 是 10 亿但只用了 1000 个,这 125 MB 仍全量分配。

  • 真实错误现象:OutOfMemoryError: Requested array size exceeds VM limit(JVM 拒绝分配超 2GB 的数组)
  • 别信“能存 21 亿个 bit”——那是理论上限,实际受限于堆大小和连续内存可用性
  • 若原始数据含负数(如 long 类型用户 ID),直接传入 set() 会转成极大正数(比如 -1L18446744073709551615),瞬间触发 OOM

cardinality() 和手动计数,哪个更适合清洗流程

cardinality() 是全量扫描内部 long[] 统计 1 的个数,时间复杂度 O(n),且每次调用都重新算;而清洗任务通常边读边判重边计数,高频更新下自己维护 uniqueCount 更快也更准。

阅读全文
标签:数据清洗

本文共计933个文字,预计阅读时间需要4分钟。

BitSet位图算法如何实现海量数据清洗中的超低内存去重过滤?

BitSet 不能直接用于海量数据。

BitSet.set(x) 为什么会 OOM?不是说它省内存吗

省的是有效数据所占的位空间,不是“按需分配”。BitSet 底层是 long[],调用 set(1_000_000_000) 时,它必须确保索引 10⁹ 能被容纳,即至少分配 ⌈10⁹ / 64⌉ ≈ 15.6M 个 long,约 125 MB 连续堆内存。如果最大 ID 是 10 亿但只用了 1000 个,这 125 MB 仍全量分配。

  • 真实错误现象:OutOfMemoryError: Requested array size exceeds VM limit(JVM 拒绝分配超 2GB 的数组)
  • 别信“能存 21 亿个 bit”——那是理论上限,实际受限于堆大小和连续内存可用性
  • 若原始数据含负数(如 long 类型用户 ID),直接传入 set() 会转成极大正数(比如 -1L18446744073709551615),瞬间触发 OOM

cardinality() 和手动计数,哪个更适合清洗流程

cardinality() 是全量扫描内部 long[] 统计 1 的个数,时间复杂度 O(n),且每次调用都重新算;而清洗任务通常边读边判重边计数,高频更新下自己维护 uniqueCount 更快也更准。

阅读全文
标签:数据清洗