如何回收 jvm 内的静态变量,以达到伪重启的效果? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
smithtel
V2EX    问与答

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

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

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

    生产环境版本: 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     Solana     3435 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 38ms UTC 04:53 PVG 12:53 LAX 21:53 JFK 00:53
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86