ManaRepair 监听主仓 OnEntityBladeStandUpdateEvent(每个刀架实体每 tick 触发):每次回调通过 ReflectionHelper.getPrivateValue(...) 反射读取事件对象私有字段 entityBladeStand(ManaRepair.java:20),无 Field 缓存;后续 Botania 缺失时的异常路径被空 catch 吞掉(:51-52),若处于该状态则每 tick 走完整反射+异常构造路径。玩家感知:多个加载中的刀架(自动化场景常见几十上百个)持续累积反射开销。
ReflectionHelper.getPrivateValue(...)
代码位置:
调用链: 刀架实体 onUpdate(每 tick/每刀架) → 主仓发布 OnEntityBladeStandUpdateEvent → ManaRepair.onUpdateBladeStand → ReflectionHelper.getPrivateValue(每次内部 findField 线性扫描类字段 + getAccessible) → 后续 Mana/TileEntity 查询
说明:反射字段查找(findField)每次对事件类做字符串匹配线性扫描,成本约为直接字段访问的百倍;主仓同类问题(实体反射构造)已修复,此处为独立出现点。
每刀架每 tick 1 次反射查找。100 个刀架 = 2000 次 findField/秒。字段查找本身 O(字段数),叠加 Botania 缺失时每 tick 异常构造(填充栈轨迹,单次数十微秒级)更重。Tick:主线程累计;GC:异常对象与反射中间对象。
重复计算:反射元数据(Field 对象)运行期恒定却每 tick 重新解析。生命周期:错误路径未做状态缓存。
private static final Field
反射目标为自有事件类,无跨模组 API 风险;Field 缓存需保持与原 getPrivateValue 相同的字段名解析结果。完全兼容。
复现条件:放置 100 个刀架并持对应刀,Spark 采样 60 秒; 观察:ReflectionHelper.findField/getPrivateValue 调用栈占比,修改前后对比。
Archive 组织仓已过时(Daniel 2026-09-23),整组织 issue 统一关闭。
No dependencies set.
The note is not visible to the blocked user.
问题描述
ManaRepair 监听主仓 OnEntityBladeStandUpdateEvent(每个刀架实体每 tick 触发):每次回调通过
ReflectionHelper.getPrivateValue(...)反射读取事件对象私有字段 entityBladeStand(ManaRepair.java:20),无 Field 缓存;后续 Botania 缺失时的异常路径被空 catch 吞掉(:51-52),若处于该状态则每 tick 走完整反射+异常构造路径。玩家感知:多个加载中的刀架(自动化场景常见几十上百个)持续累积反射开销。技术分析
代码位置:
调用链:
刀架实体 onUpdate(每 tick/每刀架)
→ 主仓发布 OnEntityBladeStandUpdateEvent
→ ManaRepair.onUpdateBladeStand
→ ReflectionHelper.getPrivateValue(每次内部 findField 线性扫描类字段 + getAccessible)
→ 后续 Mana/TileEntity 查询
说明:反射字段查找(findField)每次对事件类做字符串匹配线性扫描,成本约为直接字段访问的百倍;主仓同类问题(实体反射构造)已修复,此处为独立出现点。
影响规模
每刀架每 tick 1 次反射查找。100 个刀架 = 2000 次 findField/秒。字段查找本身 O(字段数),叠加 Botania 缺失时每 tick 异常构造(填充栈轨迹,单次数十微秒级)更重。Tick:主线程累计;GC:异常对象与反射中间对象。
根因分析
重复计算:反射元数据(Field 对象)运行期恒定却每 tick 重新解析。生命周期:错误路径未做状态缓存。
优化方向
private static final Field缓存(static {} 中一次 findField + setAccessible);保持行为:修复逻辑与触发条件不变。不影响 Forge API/Mod API/存档/网络同步。
兼容性分析
反射目标为自有事件类,无跨模组 API 风险;Field 缓存需保持与原 getPrivateValue 相同的字段名解析结果。完全兼容。
验证方案
复现条件:放置 100 个刀架并持对应刀,Spark 采样 60 秒;
观察:ReflectionHelper.findField/getPrivateValue 调用栈占比,修改前后对比。
Archive 组织仓已过时(Daniel 2026-09-23),整组织 issue 统一关闭。
[性能][中] ManaRepair 刀架每 tick 事件 ReflectionHelper.getPrivateValue 反射取字段且异常被吞to ManaRepair 刀架每 tick 事件 ReflectionHelper.getPrivateValue 反射取字段且异常被吞