V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
smithtel
V2EX  ›  问与答

如何回收 jvm 内的静态变量,以达到伪重启的效果?

  •  
  •   smithtel · 2017-03-06 17:14:13 +08:00 · 2227 次点击
    这是一个创建于 2810 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,目前所在的公司有几个在用的十分老久的系统,缓存都是用的静态变量,目前增改参数都是需要重启系统,而我们的系统过于臃肿,每次重启十分麻烦。
    目前领导提出了新需求:一个按钮清除所有缓存。
    讲道理我想辞职了,不过还是先努力一番,集思广益说不定就成了?
    求各位大佬解惑,感激不尽。

    生产环境版本: jdk 1.6

    第 1 条附言  ·  2017-03-07 16:36:21 +08:00
    今天跟老大讨论了一下技术实现,最后决定先将需求高的部分改造,不需要用缓存,我觉得我要死了。
    12 条回复    2017-03-07 16:35:10 +08:00
    kaneg
        1
    kaneg  
       2017-03-06 17:42:05 +08:00
    你明确的需求是什么? 清除缓存还是修改参数?

    如果要清除缓存,只要把相应的缓存变量清空即可,当然,前提条件这些缓存变量在你的控制范围内。
    如果是增改参数,那就提供相应的接口,外部可以控制
    simonlei
        2
    simonlei  
       2017-03-06 18:35:13 +08:00
    静态变量只是一个 ClassLoader 里面是静态的,换个新的 ClassLoader 就可以换静态变量了。 Eclipse 就是靠这种方式来达到动态加载 plugin 的。
    不过要改造老旧的系统,达到这样的效果,我觉得也是个不小的工作量。
    caixiexin
        3
    caixiexin  
       2017-03-06 19:55:31 +08:00 via Android
    是静态变量还是 final 的静态变量呢,没有 final 的话,静态变量也能重新赋值不是?
    smithtel
        4
    smithtel  
    OP
       2017-03-06 19:55:59 +08:00
    @kaneg 清除缓存,现在的问题就是并不清楚这写变量在哪,一个个去看代码,我觉得我要炸。
    @simonlei 如果将所有的 ClassLoader 替换掉,会不会有问题呢?
    smithtel
        5
    smithtel  
    OP
       2017-03-06 19:56:59 +08:00
    @caixiexin 关键是静态变量用的地方太多,很难去找,审查代码的话,几个大项目几十万行代码我觉得我能看到年中去。
    kaneg
        6
    kaneg  
       2017-03-06 20:41:44 +08:00 via iPhone
    如果都找不到这些静态变量在哪里,就算把它们重置,那你怎么让它们重新初始化呢
    SoloCompany
        7
    SoloCompany  
       2017-03-06 20:55:08 +08:00
    class loader 置换是有代价的,因为 permgen 很难被回收

    即使你的业务代码足够简单,完全没有资源竞争(不需要 listen 端口,不需要独占打开文件),因为初始化总是避免不了,你所描述的问题(重启十分麻烦)大几率还是无法避不开,问题出现在你们自己业务代码上要比在 jvm 启动上的可能高的多

    所以不要想什么捷径,该靠业务代码来 reload / 清 cache 的就别想着从外面解决

    当然你也可以尝试一下使用反射遍历所有业务 class 的静态 field ,如果是某种类型的,就执行 clear 方法;当然如果你把 [某种类型] 理解为 Map 的话,当我没说过吧
    odirus
        8
    odirus  
       2017-03-06 21:02:38 +08:00
    虽然重启复杂,但楼主还是想想怎么把重启改成自动化吧,修改代码是大忌啊,特别是老旧、没文档的系统,一不小心就引出莫名其妙的 BUG ,多想想怎么自动重启,总比你修改代码来得直接把。
    smithtel
        9
    smithtel  
    OP
       2017-03-06 21:04:50 +08:00
    @SoloCompany 啊啊啊,有很多业务代码是有持续的读写文件。不过最后这个方法倒是一个可行点,代码里面是有很多 list 和 map ,这是可以想办法去搞的。
    des
        10
    des  
       2017-03-06 21:13:04 +08:00 via Android
    同意 8 楼的,不如弄个一键重启
    zhoujinjing09
        11
    zhoujinjing09  
       2017-03-07 03:33:50 +08:00
    用 spring 的 DI ,把静态类都变成单例,应该就能热重启了
    smithtel
        12
    smithtel  
    OP
       2017-03-07 16:35:10 +08:00
    @zhoujinjing09 老系统,没有 spring
    @odirus 重启并不复杂,麻烦的是权限并不属于开发,而是分属于多人,几个系统所属部分不一样,管理员也不一样。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5403 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 53ms · UTC 07:10 · PVG 15:10 · LAX 23:10 · JFK 02:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.