190403-HashMap的key典型错误使用姿势

文章目录
  1. 1. 问题记录
  2. 2. 小结
  • II. 其他
    1. 1. 一灰灰Blog: https://liuyueyi.github.io/hexblog
    2. 2. 声明
    3. 3. 扫描关注
  • 记录一个非常低级的错误导致的java应用一直fullgc的问题;根本原因就是HashMap的key使用姿势不对

    1. 问题记录

    先捞出有问题的现场代码,之前写了一个简单的工具类,用来保存两个元素,简单的模拟了一下Guava的实现姿势

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public final class ImmutablePair<L, R> {
    @Getter
    private final L left;
    @Getter
    private final R right;

    private ImmutablePair(final L l, final R r) {
    this.left = l;
    this.right = r;
    }

    public static <L, R> ImmutablePair<L, R> of(L left, R right) {
    return new ImmutablePair<>(left, right);
    }
    }

    最开始主要是由于某些地方返回结果时,需要返回多个对象,而java并不能像python那么友好的支持这个功能,所以写了上面这个简单的工具类,对返回结果进行一个简单的封装

    距离这个工具类写完之后一两个月的时间,突然有个临时需求场景,对于每次的请求,需要做一个简单的内存过滤;如果这次请求距离上次超过5s, 则直接不处理;否则才接受;于是写了下面这段代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    private Map<ImmutablePair<String, Integer>, Long> cache = new HashMap<>();

    public String process(String k, Integer id) {
    ImmutablePair key = ImmutablePair.of(k, id);
    Long last = cache.get(key);
    long now = System.currentTimeMillis();
    if (last == null || now - last > 5000) {
    cache.put(key, now);
    return "new";
    } else {
    return null;
    }
    }

    直接看上面这段代码,貌似没有啥问题,然后愉快的跑起来;但是一段时间之后呢?内存疯狂的上涨,且一直在fullgc

    简单的测试下上面方法,发现过滤逻辑一直都没有生效

    demo

    HashMap根据Key获取Value的方式,主要是根据key的hashcode去定位对应的元素位置,然后通过equals方法判断找到的对象是不是我们预期的目标

    因为我们最上面的ImmutablePair类,没有覆盖这两个方法,所以是默认的,这个时候equals方法和==是等效的,主要是判断是否为同一个引用,所以上面的key每次都是重新创建对象,当然和缓存的不一致,从而导致每次都不命中,一直往Map里面塞数据,但是又回收不了,所以导致了这个问题

    2. 小结

    • 对于HashMap的key对象,务必保证是重写了equalshashcode方法的
    • 用内存做缓存时,使用guava的cache并设置上限,相对而言是更加优雅的方式
    • 使用HashMap时,尽量指定Map的初始化容量,否则可能出现频繁的扩容;其次就是最好能保证下HashMap的个数,毫无限制的情况下,说不准哪天就暴雷了

    II. 其他

    1. 一灰灰Bloghttps://liuyueyi.github.io/hexblog

    一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

    2. 声明

    尽信书则不如,已上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

    3. 扫描关注

    一灰灰blog

    QrCode

    知识星球

    goals

    # Map

    评论

    Your browser is out-of-date!

    Update your browser to view this website correctly. Update my browser now

    ×