Skip to content

【性能与内存占用优化】优化CRR中 captured 数据和 backup 数据,使用 IdentityHashMap 替换 ThreadLocal 作为 key 的 HashMap #817

@HuaTalk

Description

@HuaTalk

思路

CRR是框架的性能热点,会频繁创建和销毁Map对象,优化后收益较高。
captured 数据和 backup 数据中,ThreadLocal及其子类作为key使用,由于 ThreadLocal 为 ref identity,使用 IdentityHashMap 更优。

优化策略

  1. 使用IdentityHashMap替代HashMap,基于System.identityHashCode(), 使用==进行键比较,更高效的容量管理,内存占用大约减少一半,使用线性探索法局部性更好,查询性能更好。IdentityHashMap 支持 null key、null value
  2. 新增工厂方法newIdentityHashMap()
  3. 接口改用Map抽象 (向后兼容)
  4. 内部优化 (对用户无影响)

WeakHashMap为什么不改?

WeakHashMap提供弱引用语义,用于自动清理弱可达的 key 及其 entry。IdentityHashMap不支持弱引用,改不了。

涉及修改

Image

风险

如果 TTL 子类重写了equals和 hashcode 方法,会导致意想不到的问题。实际上,TTL作为Map的key时,其identity就是ref identity,应该禁止子类重写 equals和 hashcode 方法。

代码示例

修改前

private static class TtlTransmittee implements Transmittee<HashMap<TransmittableThreadLocal<Object>, Object>, HashMap<TransmittableThreadLocal<Object>, Object>> {
    @NonNull
    @Override
    public HashMap<TransmittableThreadLocal<Object>, Object> capture() {
        final HashMap<TransmittableThreadLocal<Object>, Object> ttl2Value = newHashMap(holder.get().size());
        for (TransmittableThreadLocal<Object> threadLocal : holder.get().keySet()) {
            ttl2Value.put(threadLocal, threadLocal.getTransmitteeValue());
        }
        return ttl2Value;
    }
}

修改后

private static class TtlTransmittee implements Transmittee<Map<TransmittableThreadLocal<Object>, Object>, Map<TransmittableThreadLocal<Object>, Object>> {
    @NonNull
    @Override
    public Map<TransmittableThreadLocal<Object>, Object> capture() {
        final Map<TransmittableThreadLocal<Object>, Object> ttl2Value = newIdentityHashMap(holder.get().size());
        for (TransmittableThreadLocal<Object> threadLocal : holder.get().keySet()) {
            ttl2Value.put(threadLocal, threadLocal.getTransmitteeValue());
        }
        return ttl2Value;
    }
}

参考

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions