V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GeekHub
youla
V2EX  ›  Java

请问 Java 怎么防止内存溢出?

  •  
  •   youla · 12 天前 · 2486 次点击
    • 当前遇到的问题

      • 一个老项目

      • 一个可能比我还要年长的.jar 包

      • 一个不明觉厉的类

    请问遇到这种情况怎么防止内存溢出?

    Test t=new Test();
    t.start();
    //没有找到关闭以及释放资源的方法
    
    
    26 条回复    2020-09-17 15:55:28 +08:00
    securityCoding
        1
    securityCoding   12 天前
    创建一个相同路径的类,覆盖掉它
    dijia478
        2
    dijia478   12 天前
    内存溢出?看楼主贴的代码,应该是内存泄漏导致的吧,做好高可用,然后定时重启服务。庞大的系统都是通过这种方式解决的。
    youla
        3
    youla   12 天前
    @securityCoding 这个类里面本身就 new 了很多类,也适用吗!
    youla
        4
    youla   12 天前
    @dijia478 不让重启,要 24 小时运行,崩溃,是监控。。
    wande6
        5
    wande6   12 天前
    使用钞能力,加硬件怼
    dovme
        6
    dovme   12 天前
    加内存,加到它泄漏 100 年内存都用不完,不就好了?
    lewis89
        7
    lewis89   12 天前
    上集群副本啊,溢出重启让其它的副本顶上..
    nomansky
        8
    nomansky   12 天前 via iPhone
    这不是叫内存泄露么…gc 回收不了就只能重启了
    THESDZ
        9
    THESDZ   12 天前
    多副本,滚动重启
    fhsan
        10
    fhsan   12 天前
    多个副本,监控自动重启,加内存加机器根本不可取
    hecz
        11
    hecz   12 天前
    @youla 分批部署都不行?
    kingfalse
        12
    kingfalse   12 天前
    1 》 sh 脚本里面写个死循环执行 java -jar ,
    2 》程序里面 new Thread 然后 sleep 一个小时,然后 exit

    反正就是等他内存崩之前,你先自杀重启,完美符合题意.
    手动狗头保命 /doge/doge/doge
    Marine5174
        13
    Marine5174   12 天前
    LZ dump heap 了吗? 确定是这个类泄漏造成的内存溢出吗?
    securityCoding
        14
    securityCoding   12 天前
    @youla 直接上字节码增强吧 , 实现原理参考一下 arthas 源码
    youla
        15
    youla   12 天前
    @Marine5174 我确定!我在寻找一个解决办法,希望能找到或者记录这个类从实例化到调用产生出来的新事物,然后结束时一并释放。
    youla
        16
    youla   12 天前
    @fhsan
    @THESDZ
    @lewis89 不用规避的手段!!
    lewis89
        17
    lewis89   12 天前
    @youla #16 不规避.. 老哥这种陈年烂项目 不用这么上心
    THESDZ
        18
    THESDZ   12 天前
    那就把这个内部改为线程池,限制他的内存,改造会导致什么问题,得看具体代码和业务
    youla
        19
    youla   12 天前
    @lewis89 产生了相应的需求,不得不做
    araaaa
        20
    araaaa   12 天前 via iPhone
    定时重启
    ic2y
        21
    ic2y   12 天前
    @youla 在启动脚本里,加上 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/heap/java.dump 然后运行一把程序,让他内存溢出崩溃。 然后用 MAT 软件分析 /path/heap/java.dump 文件,看看是谁导致了溢出,修正之,再往复循环测试。 直到不崩溃。
    neoblackcap
        22
    neoblackcap   12 天前
    @youla 你说不用规避的手段,那就是你去修掉内存泄漏的 bug 。否则所有方法都是规避手段。
    whp1473
        23
    whp1473   11 天前
    首先你确定是这个类造成的么?
    第一、Test t=new Test(); t.start();创建后方法出栈就会判定为可回收了,gc 会自动垃圾回收。如果不确定,用 JVM VisualVM 分析 dump 日志,找到堆中最多的类,分析为什么该类被一直持有
    第二、Test t=new Test(); t.start();如果是一个线程,一直运行,那说明里面有 while 死循环,并一直持有对象的地址和一直 new 对象导致,也可能是阻塞导致对象不被释放,比如 Http 不设置超时时间等。如果是古老的包,可以考虑继承、代理模式、AOP 等方式替换接口实现,来修复该 BUG 。
    第三、如果都没有问题,Test 就是每个用户请求就要有一个,那建议加大 JVM 堆内存,同时使用更好的机器,以及对机器限流和用 ng 做复杂均衡,将请求均匀分布在更多的机器上
    youla
        24
    youla   11 天前
    @whp1473 你好,我也不太熟悉 Java,这个类里面可能封装了 io 包里面的一些类没有及时 close,想请教下这种情况会回收吗?
    whp1473
        25
    whp1473   10 天前
    @youla JVM 会自动关闭并回收,但是一般都应手动关闭,否则会一直占用无用资源。更多的情况应该是阻塞导致的。还有如果有 static 要注意,比如这种 private List<对象> list = new ArrayList<>(); list 中放入 IO,那永远不会被释放。
    youla
        26
    youla   10 天前
    @whp1473 好的,多谢指教。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4626 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 02:26 · PVG 10:26 · LAX 19:26 · JFK 22:26
    ♥ Do have faith in what you're doing.