这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
《Java 虚拟机原理与性能调优》5.3 收集器谱系:Serial、Parallel、G1、ZGC 与 Shenandoah
五种收集器在同一台 M1 Pro、同一份负载下的真实对照:Serial 与 Parallel 的日志形状、G1 的 region、ZGC 的 0.053ms 最大停顿和 Shenandoah 的 256K region,附选型表与可复现命令。
posts
这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
五种收集器在同一台 M1 Pro、同一份负载下的真实对照:Serial 与 Parallel 的日志形状、G1 的 region、ZGC 的 0.053ms 最大停顿和 Shenandoah 的 256K region,附选型表与可复现命令。
从 arch-lab 订单服务一次 3 秒网络抖动导致 12 个实例被全部剔除的事故出发,区分 TTL 租约、主动健康检查与流量状态,说明剔除阈值、恢复观察窗口和成功次数如何抑制抖动,给出标准库 Go 注册表实现与真实测试输出,并列出实例生命周期的常见边界。
把交易端最容易混淆的状态与金额字段收在一张表里:订单、支付、退款三套状态机各自的取值、迁移与终态,金额从商品价到应付、实付再到退款的分段口径与字段命名,状态之间的禁止组合,以及展示文案、按钮可用性和事件时序的对照,供评审、联调与线上排查时随手查用。
从支付回调成功后主库宕机、切换后备库缺少最后一笔订单的场景,拆解复制滞后、提交位点与故障切换的关系;用可运行的 Go 模型计算未复制尾部如何变成 RPO,比较异步与半同步的确认集合,并给出切换前的位点检查清单,说明半同步确认集合与提升候选不一致时为何仍会丢数据。
同样一段分配负载,Serial 打印 DefNew/Tenured,Parallel 打印 PSYoungGen/ParOldGen,G1 打印的是一串 region 计数。本节用三份真实 GC 日志拆开分代假设、三种回收算法与晋升年龄,并在 -Xmx64m 下量出年龄表最高只到 age 6。
用两地同时修改同一订单收货地址的场景,说明多主写入的冲突来源与最后写入获胜的丢更新问题;实现版本向量并发检测、PN-Counter 与 add-wins OR-Set 合并,并用枚举验证 R+W>N 的读写重叠条件,说明为何它只是必要条件而非强一致证明。
主城装不下就开分线,副本要独立规则,SLG 的大地图分片却不是分线。本节区分四种“世界切开”的方式,给出跨线迁移的冻结、令牌与 epoch 协议,讨论容量阈值、迟滞与回收策略如何避免频繁抖动,并用可运行的 Go 包演示状态归属与旧线拒绝写入。
从大促中“支付成功却显示待支付”的订单详情页切入,区分复制日志的写入、提交与应用三种位点,说明强制读主和固定 sleep 为什么都不可靠;用可运行的 Go 单主复制包实现会话令牌与读己之写,并测试主库切换后未提交尾部被丢弃、位点不足时必须显式报错。
穷尽 switch 只解决了「分支是否齐全」,没有解决 null、守卫顺序和模式嵌套过深。本节用 LoanState 演示 case null 的三种写法、when 守卫的求值规则、模式支配的编译错误,并说明 JDK 25 中 primitive patterns 仍是预览特性,不能带进生产代码。
libraryd 的 LoanCache 清了引用还占着 1.2 GB。本节用 GC Root 实验、弱/软/虚引用与 Cleaner 的真实输出,量出 -Xmx64m 下软引用只剩 16/4096,并解释 WeakHashMap 为什么留不住条目。
ErrorCode 枚举加 default 分支的问题不是写法丑,而是新增错误码时编译器不会提醒任何消费方。本节用 LoanState 和 LoanResult 的 sealed 层次演示穷尽 switch,真实编译一次「新增子类型」的失败,并给出 libraryd 中罚金、下一步动作与 HTTP 映射的落地代码。
加载一个插件类,热了五分钟的接口调用突然退回解释器。本节用 -XX:+PrintCompilation 抓 marked for deoptimization 与 uncommon trap,用 JFR 的 jdk.Deoptimization 事件看 class_check 的 bci、原因与动作,再解释 OSR 为什么在循环中途换代码,以及 libraryd 插件热加载该怎么避开反优化。
「回声」为智能回复选模型,三个月里争论三次、结论三次,却没人说得清上一次为什么那样定。本节把质量、成本与延迟的取舍写成 ADR:先用护栏排除不可行方案,再按显式优先级选择,用六个可计算条件触发复核,并附可测试的 TypeScript 实现。
借阅结果从 service 传到 HTTP 层时,instanceof 加强制转换把类型判断和取值拆成两段。本节用 record pattern 把 LoanResult、LoanState 和嵌套 record 一次解构,讨论未命名模式、守卫与泛型擦除带来的边界,并给出可编译的 libraryd 展示层代码。
同样的罚金计算,走单态调用是 0.71 ns/op,双态调用点约 2.13 ns/op,四实现的巨态调用是 3.34 ns/op。本节用 -XX:+PrintInlining 读内联与拒绝原因,用 -XX:-DoEscapeAnalysis 对照 GC 次数,再用 JMH 1.37 跑单态、双态与巨态分派,最后落到 libraryd 的 FinePolicy 策略设计。
虚拟线程让等待变便宜,但不会让连接变多。本节用 400 个任务打 10 个连接的实验说明并发度仍要显式限制,用池化线程上的 ThreadLocal 泄漏演示请求串号,再用 ScopedValue 与令牌桶给出 libraryd 的三件套落地写法。
引擎与原生壳的边界不按技术栈划分,而按十项职责的所有权划分:生命周期、主线程与权限归壳,渲染线程归引擎,文件路径、网络传输与传感器共享。本节把这份判定表写成可查询、可审计的 Host 契约,并用五条断言防止职责重复或缺席;表外的灰区必须显式登记,不能留给下一版口头约定。
从 order-service 改金额字段导致三个消费者在预发同时失败的事故切入,说明 provider 自测为何证明不了消费者,给出把消费者期望、provider 样例与 CI 合并门禁串起来的单包 Go 实现、真实测试输出,以及契约版本、缺失样例和类型收紧的处置规则。
《裂隙战场》《群岛纪元》《泡泡工坊》三个场景的 AOI 选型不能只看数据结构排名。本节先按在线人数、视野半径和同步频率估算消息量,再对比九宫格、十字链表与空间索引的实现成本、边界穿越和动态实体适应性,并给出从网格切换到空间索引的触发条件与可运行代码。
同一个 FinePolicy.fineCents,启动时跑在解释器里,几十毫秒后已经被 C2 编译。本节用 -XX:+PrintCompilation 的真实输出拆解列含义与 tier 3/4 迁移,用 jcmd Compiler.queue、Compiler.codecache 看编译队列和代码缓存,并对照 -XX:TieredStopAtLevel=1 的峰值与启动耗时。