293 MB293 MB293 MB
当 val 小于 128B 时,初始化 map 后内存占用量一直不变 。原因是 put 操作只是在 bucket 里原地写入 val,而 delete 操作则是将 val 清零,bucket 本身还在 。因此,内存占用大小不变 。
而当 val 大小超过 128B 后,bucket 不会直接放 val,转而变成一个指针 。我们将 N 设为 129,运行程序:
0 MB197 MB38 MB
虽然 map 的 bucket 占用内存量依然存在,但 val 改成指针存储后内存占用量大大降低 。且 val 被删掉后,内存占用量确实降低了 。
总之,map 的 buckets 数只会增,不会降 。所以在流量冲击后,map 的 buckets 数增长到一定值,之后即使把元素都删了也无济于事 。内存占用还是在,因为 buckets 占用的内存不会少 。
对于 map 内存泄露的解法:
- 重启;
- 将 val 类型改成指针;
- 定期地将 map 里的元素全量拷贝到另一个 map 里 。
经验总结扩展阅读
- Java8中那些方便又实用的Map函数
- Spring Boot 中使用 tkMapper
- 重大发现,AQS加锁机制竟然跟Synchronized有惊人的相似
- 海信智能电视质量怎么样 用户竟然这么评价
- 信号量 C# 多线程访问之 SemaphoreSlim【C# 进阶】
- 小白也会 HTML 动态爱心-详细教程
- MyBatis笔记03------XXXMapper.xml文件解析
- 【Azure 事件中心】Event Hub 无法连接,出现 Did not observe any item or terminal signal within 60000ms in 'flatMapMany' 的错误消息
- 云小课|MRS基础原理之MapReduce介绍
- Redis系列8:Bitmap实现亿万级数据计算