为什么这个程序会内存泄漏? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
LudwigWS
V2EX    Java

为什么这个程序会内存泄漏?

  •  
  •   LudwigWS 2020-08-03 18:04:01 +08:00 4376 次点击
    这是一个创建于 1894 天前的主题,其中的信息可能已经有所发展或是发生改变。

    该程序后期会不断 GC,但是又无法回收多少内存,最终可能会 OOM

    import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor; import java.til.concurrent.TimeUnit; /** * 从数据库中读取信用数据,套用模型,并把结果进行记录和传输 */ public class T15_FullGC_Problem01 { private static class CardInfo { BigDecimal price = new BigDecimal(0.0); String name = "张三"; int age = 5; Date birthdate = new Date(); public void m() {} } private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50, new ThreadPoolExecutor.DiscardOldestPolicy()); public static void main(String[] args) throws Exception { executor.setMaximumPoolSize(50); for (;;){ modelFit(); Thread.sleep(100); } } private static void modelFit(){ List<CardInfo> taskList = getAllCardInfo(); taskList.forEach(info -> { // do something executor.scheduleWithFixedDelay(() -> { //do sth with info info.m(); }, 2, 3, TimeUnit.SECONDS); }); } private static List<CardInfo> getAllCardInfo(){ List<CardInfo> taskList = new ArrayList<>(); for (int i = 0; i < 100; i++) { CardInfo ci = new CardInfo(); taskList.add(ci); } return taskList; } } 
    8 条回复    2020-08-03 21:01:08 +08:00
    senninha
        1
    senninha  
       2020-08-03 18:30:35 +08:00
    CardInfo 一个都回收不了,这不就内存泄漏了。
    ChanKc
        2
    ChanKc  
       2020-08-03 19:09:32 +08:00 via Android
    一直都在加 cardinfo 而且 executor 来不及执行所以越来越多?
    LudwigWS
        3
    LudwigWS  
    OP
       2020-08-03 19:22:37 +08:00
    @senninha
    请问一下为什么 CardInfo 回收不了?线程池满了以后旧的任务被抛弃了,按理说垃圾回收器不是能回收了么。
    airfling
        4
    airfling  
       2020-08-03 19:36:12 +08:00
    回收不了的,CardInfo 被 Runnable 隐式调用,ScheduledThreadPoolExecutor 你看的是核心线程是 50,但是任务队列应该是无线大的
    yannxia
        5
    yannxia  
       2020-08-03 19:46:11 +08:00
    cardinfo 在 threadpool 的 queue 里面了,虽然都没有实际调用,但是的确是越来越多的。调整 scheduleWithFixedDelay 的速度 或者把 queue 改小。
    asd123456cxz
        6
    asd123456cxz  
       2020-08-03 20:09:08 +08:00
    ScheduledThreadPoolExecutor 使用的是 DelayedWorkQueue,它在提交队列到容量上限时会进行扩容,即不会触发 discard 。
    仅看了下源码,没有验证,有问题请指正
    senninha
        7
    senninha  
       2020-08-03 20:23:45 +08:00
    @LudwigWS 大兄弟,一个 CardInfo 就 96B 了,一个任务加进队列还要包装几层,应该有 200B+。而默认的工作队列会膨胀到 Integer.MAX_VALUE,都跑不到 reject 内存就已经炸了啊。
    LudwigWS
        8
    LudwigWS  
    OP
       2020-08-03 21:01:08 +08:00
    @ChanKc
    @airfling
    @yannxia
    @asd123456cxz
    @senninha
    这个构造器默认最大队列容量是 Integer.MAX_VALUE,当提到这一点的时候我瞬间就明白了,哈哈哈。还是想当然了,把核心线程数当作拒绝临界点。所以也是这个问题比较隐蔽的原因。

    我还以为是这里的内存泄漏涉及到垃圾回收器的回收算法,没想到只是使用上的问题。

    感谢各位
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     892 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 20:49 PVG 04:49 LAX 13:49 JFK 16:49
    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