MOsky
2015-08-01 23:52:07 +08:00
以前我在游戏公司上班的时候考虑过这个问题。
一种是 Java 有一个什么机制(忘了名字,去网上搜吧)可以在 JVM 运行阶段动态替换类方法的实现。Eclipse 的 debug 模式好像就是用这种方法来允许你调试的时候动态改代码的。
这种模式有个问题,如果是生产服务器用这个热更新的话,比较乱来,不够让人安心。
另一个方案就是如楼上所说的 ClassLoader。
这个方案比上一个方案要安全得多。但是存在两个问题。
1. 比较难管理。Java 无法主动卸载 ClassLoader 实例,只能等实例变成不可达,然后等 GC 清理掉。这要求你清楚的知道 ClassLoader 会被哪些(有一堆乱七八糟的候选项目)对象直接或间接引用。
这必须要求你的服务器业务模块之间藕合度极低(主要是模块之间调用传的参数和返回值必须是Java标准对象,不可直接或间接引用各种需要 ClassLoader 载入的封装对象)。如果做不到,你的生产服务器可能同时运行新旧两种业务代码,就只好哭爹喊娘了。
对于游戏服务器业务,好像很不好写啊。又不是 servlet,servlet 就随随便便热加载。
2. 如果你不幸生产服务器使用的是 Java 6 以及以下版本,那么你可能会遇到方法区内存用光的问题。如果你使用 Java 7 ,那恭喜你,Java 7 的方法区取消了,直接挪堆区,你完全不必关心这个问题。GC 迟早能卸载旧的代码。
最后,这两种方案最终没有一种被弃用。还是按照老方法要更新服务器就重启服务器,全服玩家全部滚下线候着吧。以上只是纸上谈兵。