找回密码
 立即注册
首页 业界区 业界 keycloak~深入了解DefaultSegmentedDataContainer对象解 ...

keycloak~深入了解DefaultSegmentedDataContainer对象解决内存泄漏

禄磊 4 天前

  • 源码来自infinispan: git@github.com:infinispan/infinispan.git
基于Infinispan 内部架构的了解,让我为你详细解释 DefaultSegmentedDataContainer 中 TTL 的存储位置:
DefaultSegmentedDataContainer 中 TTL 的存储结构

核心结构层次
  1. DefaultSegmentedDataContainer
  2. ├── DataSegment[] segments  ← 分段数组(根据 key 的 hash 分配)
  3. │   │
  4. │   └── ConcurrentHashMap<Object, InternalCacheEntry>
  5. │       │
  6. │       └── InternalCacheEntry<K, V>  ← 每个缓存条目对象
  7. │           │
  8. │           ├── key          : K         ← 缓存键
  9. │           ├── value        : V         ← 缓存值
  10. │           ├── metadata     : Metadata  ← 元数据(包含TTL信息)★
  11. │           ├── created      : long      ← 创建时间戳
  12. │           └── lastUsed     : long      ← 最后访问时间戳
复制代码
TTL 信息的具体位置

TTL 不是存储在 DefaultSegmentedDataContainer 的直接属性中,而是在每个 InternalCacheEntry 对象的 Metadata 属性里。
Infinispan 中有多种 InternalCacheEntry 实现类,根据是否有过期时间分类:
实现类特点TTL 相关属性ImmortalCacheEntry永不过期无 TTL 属性MortalCacheEntry有 lifespanlifespan, createdTransientCacheEntry有 maxIdlemaxIdle, lastUsedTransientMortalCacheEntry同时有两者lifespan, maxIdle, created, lastUsedMetadataImmortalCacheEntry使用 Metadata 对象metadata.lifespan(), metadata.maxIdle()MetadataMortalCacheEntry使用 Metadata 对象metadata.lifespan(), metadata.maxIdle()下面的缓存sessions表示永不过期,因为它的类型是ImmortalCacheEntry

1.png

下面的缓存sessions是有过期时间的,它的类型是TransientMortalCacheEntry

2.png

实际的 TTL 属性
  1. 对于 Keycloak 的会话缓存,通常使用 **带 Metadata 的条目**,TTL 信息在:
复制代码
  1. InternalCacheEntry entry = ...;
  2. // 获取 lifespan (生命周期 TTL)
  3. long lifespan = entry.getLifespan();      // 返回毫秒值,-1 表示永不过期
  4. // 获取 maxIdle (空闲 TTL)  
  5. long maxIdle = entry.getMaxIdle();        // 返回毫秒值,-1 表示永不过期
  6. // 获取创建时间
  7. long created = entry.getCreated();        // 创建时的时间戳
  8. // 获取最后访问时间
  9. long lastUsed = entry.getLastUsed();      // 最后访问的时间戳
  10. // 检查是否过期
  11. boolean expired = entry.isExpired(System.currentTimeMillis());
  12. // 计算过期时间点
  13. long expiryTime = entry.expiryTime();     // 返回具体的过期时间戳
复制代码
在 JVM 调试时查看 TTL

如果你想在调试器中查看某个缓存项的 TTL,路径是:
  1. DefaultSegmentedDataContainer
  2.   └── segments (DataSegment[])
  3.       └── [segment index]
  4.           └── entries (ConcurrentHashMap)
  5.               └── [key]
  6.                   └── InternalCacheEntry 对象
  7.                       ├── metadata
  8.                       │   ├── lifespan   ← 这里是 TTL(毫秒)
  9.                       │   └── maxIdle    ← 这里是空闲超时(毫秒)
  10.                       ├── created        ← 创建时间戳
  11.                       └── lastUsed       ← 最后访问时间戳
复制代码
过期判断逻辑

[code]// 在 InternalCacheEntry 中的过期检查逻辑(简化版):public boolean isExpired(long now) {    // lifespan 检查    if (lifespan > 0 && (created + lifespan)  0 && (lastUsed + maxIdle)  0 && (created + lifespan)  0 && (lastUsed + maxIdle)

相关推荐

您需要登录后才可以回帖 登录 | 立即注册