区域缓存上限(region-cache-size)

基本信息

属性 值
作用 SharedCache.DEFAULT 一次打开的区域文件(FileChannel)数量上限
调节方式 JVM system property(不是 FML config 文件)
属性键 cubicchunks.regionlib.maxRegionCacheSize
默认值 "256"(Integer.parseUnsignedInt 解析)
读取位置 lib/provider/SharedCache.java:31(public static final SharedCache DEFAULT 静态初始化)
生效时机 类加载时读一次,之后改系统属性无效;必须用 -D 在 JVM 启动参数里传

⚠️ 本 mod 没有任何 Forge 配置文件。全仓库 grep -rn "@Config\|Configuration\|ForgeConfiguration" src/ 零命中——cubicchunks.regionlib.maxRegionCacheSize 是本 mod 唯一的可调参数。

行为

SharedCachedRegionProvider 在需要读写某个 key 时,会向 SharedCache 借一个票(Semaphore)打开对应的 region 文件;票用尽就触发清理。SharedCache 用 ConcurrentHashMap#compute 保证同一个 region 同一时刻只被一个线程触碰。

软 / 硬两级限流:

字段 计算式 含义
maxCacheSize 构造参数 硬上限,等于票的总数
softCleanupThreshold max(1, maxCacheSize - max(1, min(maxCacheSize >> 3, availableProcessors() << 1))) 低于该占用量时清理请求直接忽略
cache new ConcurrentHashMap<>(max(maxCacheSize << 1, maxCacheSize)) 容量翻倍以避免 rehash
availableTickets new Semaphore(maxCacheSize) 每开一个 region 消耗一张票
cleanupRunning new Semaphore(1) 全局只允许一个清理线程
openCounter new AtomicLong(Long.MIN_VALUE) 起 记录打开次序,用于 LRU 近似淘汰

参数校验(SharedCache(int maxCacheSize)):

输入 结果
maxCacheSize <= 0 抛 IllegalArgumentException("maxCacheSize must be positive!")
maxCacheSize < 2 抛 IllegalArgumentException("maxCacheSize must be at least 2!")

清理策略 cleanup0(boolean force, boolean full):

  • force == true(close() 走这条路):cleanupRunning.acquireUninterruptibly() 阻塞直到拿到清理权
  • force == false:usedTickets == 0(full 模式)或 usedTickets < softCleanupThreshold(普通模式)直接返回 false;cleanupRunning.tryAcquire() 失败说明已有清理在跑,也返回 false——普通清理永不阻塞其他线程
  • 过期阈值:full 时 Long.MAX_VALUE(全清),否则 openCounter.get() - (usedTickets >> 1)(淘汰最近一半)
  • 逐个 cache.compute 关闭 region 并 availableTickets.release() 归还票;关闭异常被收进一个 new IOException() 再 rethrow(用 addSuppressed 挂载每个子异常)

缓存键 SharedCacheKey<K> = (RegionKey, IRegionFactory 引用身份),hashCode = regionKey.hashCode() * 31 + regionFactory.hashCode()。同一个目录用不同工厂打开会被当成不同条目。

数值

数值 默认值 备注
cubicchunks.regionlib.maxRegionCacheSize 256 Integer.parseUnsignedInt,写负数会抛 NumberFormatException
单条目最大字节数 255 扇区 见 区域文件格式

关闭语义

调用 行为
SharedCachedRegionProvider.close() 置 volatile closed = true 并 cache.close();二次调用抛 IllegalStateException("Already closed")
SharedCachedRegionProvider 其余全部方法 closed 后调用同样抛 IllegalStateException("Already closed")
SharedCache.flush() 遍历 cache 调 region.flush();若期间 region 已被并发关闭则跳过

相关条目

  • 区域文件格式 - 缓存里放的是什么文件、单条目为什么有 255 扇区上限
  • 多提供者回退链 - 一个 SaveSection 背后可能同时挂着多个 IRegionProvider,各自共用同一份 SharedCache.DEFAULT