Java 版运行时
2009 年选 Java 的收益(可移植、可反编译)与代价(GC 停顿、内存、启动);运行时税的偿还史;LWJGL 与原生边界;语言是偶然,偶然长出的生态已成本质。
本章命题:Java 是 2009 年语境下的正确选择——它同时交付了可移植性(一次编写、全平台运行)与可反向性(字节码可还原,模组生态的技术地基),代价是运行时税(GC 停顿、内存占用、启动慢),而税的大半已被十五年的工程演进偿还。语言选择是历史偶然,但它长出的生态已经织进本质;任何「必须换语言」或「绝不能换」的单边结论都错。
1问题
「Minecraft 卡是因为 Java。」——这句话是玩家社区流传最广的技术判断,也是半对半错的典型。说它对:Java 确实带来了真实的运行时开销,早期的 Minecraft 确实受制于它。说它错:今天的 Minecraft 在现代 JVM 上跑得不慢,而当年它若选了别的语言,大概率活不到能被优化的一天。
语言选择是软件工程里最像「出身」的东西:它不决定你成为什么,但决定你最容易长成什么。本章把这门「出身」的账完整算一遍:2009 年的选项里 Java 对在哪、代价是什么、税怎么一年年还掉、引擎与原生世界的边界在哪——最后回答卷四必然要问的问题:语言是本质还是偶然?(预告:答案是双边的。)
2009 年的正确选择
评价一个技术选择,必须先回到选项池。2009 年,一个瑞典下班程序员要写一款跨平台的三维游戏,现实选项大致三条:C++——性能王者,但跨平台意味着为 Windows、macOS、Linux 分别处理构建与系统差异,一个人付不起这个工程成本;Flash——浏览器触达无敌,但三维能力孱弱,撑不起体素世界;Java——一次编写到处运行,三维有现成的 OpenGL 绑定(LWJGL,一个把 OpenGL、OpenAL 这些原生库包给 Java 用的轻量库1),还有一门独门绝技后面再讲。
Java 在这个选项池里几乎是排他的答案。可移植性对早期 Minecraft 不是锦上添花,是传播战略本身:玩家的朋友可能用任何系统,官方买不起任何一家平台的应用商店位,Java 让「发一个 jar 文件,什么电脑都能跑」成立——卷一第 2 章讲过的口碑增长引擎,烧的正是这份可移植性。浏览器试玩(当年的 Java applet 技术,网页里直接跑 Java 程序)让「点开链接就玩」成为 2009 年最顺滑的入口——这门技术后来死了,但它在增长期立过功。
而那门独门绝技——字节码可反向——的生态意义,卷三第 12 章已经完整算过账:Java 程序发布的是半成品的中间码,工具可以把它还原成接近可读的源码,社区因此读得懂、改得动游戏本体,ModLoader、Forge 到整个模组纪元的最后一环技术前提,就是这门语言自己。可移植性给了传播,可反向性给了生态——Java 对 Minecraft 的馈赠,没有一样写在性能栏里。
3运行时税:GC、热路径与启动
代价同样是真实的,主要三项。
**GC 停顿。**Java 的内存管理由垃圾回收器(GC)代劳:程序只管分配,回收器定期清扫不再使用的对象。代价是回收的某些阶段要「暂停世界」——专业术语叫停顿(stop-the-world),字面意思:清扫期间所有应用线程站住别动。停顿几毫秒到几十毫秒,玩家体感为偶发的小卡顿(stutter)。Minecraft 的世界更新每刻都在分配大量短命对象(第 4、5 章的连锁更新与实体结算都是分配大户),正好踩在 GC 最忙的工况上——好消息是这类短命对象恰好是 GC 最擅长处理的品种(生得快死得早的对象可以被极快地回收),坏消息是每刻都来一批,账单永不停歇。
**内存占用。**JVM 与 Java 对象模型有固定开销:每个对象带对象头,每个世界方块若按对象建模都是一笔 overhead(实际实现早就不这么存方块——调色板与位打包,第 1 章——但实体、界面、字符串依然是对象海洋)。同等画面,Java 版的内存占用普遍高于等价的原生实现。
**启动时间。**JVM 冷启动要加载与校验海量类文件,加上 JIT(即时编译器)需要先运行才能把热代码编译成机器码——「打开游戏等半天,进去还要再卡一阵」的体验,一半是类加载,一半是 JIT 预热。
三项税的共同形状:它们不是常数,是随规模与活动波动的活账——世界越大、实体越多、机器越复杂,税越重。这也是为什么「实体才是税」(第 6 章)与「Java 税」经常被混为一谈:很多「Java 卡」其实是实体税,只是账单都寄到了语言头上。
4性能史:一笔税的偿还记录
十五年下来,这三笔税还得怎么样了?账面比社区印象好得多。
JVM 自身的进步是大头:新一代垃圾回收器把停顿压到毫秒级且更均匀,JIT 的优化一代比一代激进——同一份代码,今天的 Java 跑得比 2010 年快得多,「Java 慢」这个印象的时效性早就过了。官方的优化逐版推进:光照引擎重写(第 4 章)、区块网格化改进(第 9 章)、实体与调度的持续调优——官方的优先级虽然从不把性能放第一,但账一直在慢慢还。社区的性能模组是还不完的那部分的承包商(第 9 章的「民间官方实现」):渲染层的 Sodium 一系、逻辑层的各类优化 mod、服务端 Paper 精调的 GC 参数——它们证明的最重要事实是:剩余的性能差距是渲染与算法层的,不是语言层的。同一台机器,换了实现 Java 也能飞;瓶颈在哪一层的诊断,社区已经用对照实验做完了。
所以到今天还剩下的真税只有一笔:结构性的对象模型开销与 GC 的存在本身——它让 Java 版的极限性能天花板低于理论上的原生实现。这笔税真实存在,但它处在「发烧友跑分」的层面,不在「玩家体验」的层面——对绝大多数玩家,今天的 Java 版瓶颈是渲染算法,不是语言。
性能史里还有一个非跑分的赢家要单独记:官方启动器与版本隔离。Java 的发布形态(一个 jar 文件,卷一第 2 章讲过)让「同一台电脑并存任意多个版本」在技术上近乎免费——启动器把每个版本的文件放进各自独立的目录(版本隔离),玩家可以在今天的最新版与 2012 年的老版之间自由切换,互不污染。卷一第 13 章讲过这件事的文化重量(旧存档有官方后门可回),这里补上它的技术根源:Java 的发布形态 + 启动器的目录管理,共同构成了这个游戏「历史可回访」的架构基础。Bedrock 版做不到这一点(应用商店只发最新版),第 15 章会把这组对照补完。顺带一提,启动器本身也是 Java 技术债的清理现场:它自己从臃肿的旧版重写成了轻量的现代应用——连看门人都在还债,这个家的债务文化可见一斑。
服务端一侧的偿还史同样值得一提:大型服务器的主机调优(Paper 一系,第 16 章展开)有相当比例的工作是JVM 调优——选更合适的垃圾回收器、调堆大小、优化参数组合。同一份服务端代码,在调优前后的机器上表现判若两台——这门「给 JVM 体检」的手艺是服务器运维的核心技能之一,它也从侧面证明:Java 的性能下限低,但上限的门是开着的,钥匙在运维手里。
5原生库与渲染后端:Java 世界的国境线
Java 并非孤岛。LWJGL 是它的海关:OpenGL(渲染)、OpenAL(音频)、GLFW(窗口与输入)这些 C 语言世界的原生库,通过 JNI(Java 调用原生代码的官方桥)接进游戏。渲染后端的历史就是这条海关的贸易史:从旧式 OpenGL 用法到现代核心管线的迁移(第 9 章的渲染简史),每一次换代都在 JNI 边界上重新谈判——原生调用的来回有固定成本,边界上的设计(把多少工作留给原生、多少留在 Java 侧)是性能敏感的精细活。
这条国境线还有一个容易被误读的地方:「Java 游戏卡」的账单里,常混着原生库与驱动层的账。驱动的兼容问题、OpenGL 的调度、显卡厂商的实现差异——这些无论用什么语言都要面对的麻烦,因为发生在「Java 游戏」身上,也一并被记在了 Java 头上。语言背负的骂名,一部分是替整条技术栈背的。
6偶然 vs 本质:双边结论
现在可以交付本章的验收结论了,按纪律,双边。
**Java 证明了什么:**语言的选择可以是生态战略。可移植性让一个独立游戏完成全网传播,可反向性让玩家的修改成为产品的第二作者席——这两样都不是「语言的性能」,而是「语言的社会学」。如果没有 Java,2009 年的 Minecraft 也许性能更好,但很可能既传不开(跨平台成本),也改不动(不可反编译)——它会更像一个「游戏」,而长不成一个「媒介」。
**Java 卡住了什么:**性能天花板的结构性折价、启动与内存的体验税,以及一条隐性的:官方长期可以对性能不设 KPI(「反正 Java 就这样」是个太方便的挡箭牌)——债能外包(第 9 章),不代表欠得理直气壮。
语言是偶然还是本质:选 Java 是偶然(Notch 最熟的手艺),但这个偶然长出的东西——可反编译的生态、LWJGL 的边界、整个工具链——已经成了「Minecraft 是什么」的一部分。换语言的真代价不是重写那几十万行引擎代码(卷四会论证那是可行的),而是重写围绕语言长出来的整个社会:模组工具链、反混淆映射、性能模组、服务端生态。偶然早已编织进本质——这正是卷四第 3 章「可以抛弃的历史偶然」要拆解的第一案。
7这一章留下什么
- 爱好者:下次听到「Java 所以卡」,可以补一句:Java 所以能装模组、能跨平台、能活十五年——卡的那部分,社区和官方还了十五年,已经还得差不多了。
- 开发者:能抄走的是语言选择的生态学评估——评估一门语言,除了性能表,还要评估「它让玩家能对你做什么」(可移植 = 传播,可反向 = 生态);以及「税收进度表」的诚实:把运行时的代价写成可偿还的分期账,而不是一次性否决。抄不走的是时机:2009 年 Java 是最优解不等于今天是,技术选型的有效期以生态冻结日为止。
注释
-
Wikipedia,《Lightweight Java Game Library》(LWJGL:为 Java 提供 OpenGL、OpenAL 等原生库绑定的开源库,Minecraft 的底层依赖),维基百科,检索于 2026-09-18;见 https://en.wikipedia.org/wiki/LWJGL ↩