关于 Java 内存泄露的问题,请各位大佬帮我看看 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
moxiaowei
V2EX    Java

关于 Java 内存泄露的问题,请各位大佬帮我看看

  •  
  •   moxiaowei 2022-06-30 15:58:20 +08:00 3306 次点击
    这是一个创建于 1249 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有一个类,这个类有一个静态属性,长这样:public static A a =new A(); 那么现在来分析,new A()肯定是进 JVM 的堆区,static A a 肯定是进方法区,然后 "=" 是把方法区的 a 与堆区的数据进行一个强引用关联。那么问题来了,方法区的数据一般不会被清理掉(特殊情况除外),那么指向堆内存的数据就会一直在堆中存在,这不就是内存泄露了么?

    20 条回复    2022-07-13 15:52:01 +08:00
    7911364440
        1
    7911364440  
       2022-06-30 16:03:58 +08:00
    不算内存泄漏吧,我的理解是如果 A a 被清理掉之后,new A()没有被清理掉才算内存泄露
    chtcrack
        2
    chtcrack  
       2022-06-30 16:06:24 +08:00
    你 new 出来的不用得销毁啊,否则肯定内存泄漏,c/c++是这样的,java 不知道,原理应该差不多吧.
    Jooooooooo
        3
    Jooooooooo  
       2022-06-30 16:08:26 +08:00
    你想讨论的问题是, 什么叫做"内存泄露"

    你描述的场景, 按照通常的理解, 不是"内存泄露"

    当然, 如果你把你所描述的场景圈起来, 并且把它算成"内存泄露"的定义范围, 那它就是"内存泄露", 但很明显这样的回答你不能满意

    所以若是你想解决定义问题, 那这个意义不大

    如果你想解决的是因为这种写法导致内存越来越大的问题, 那就把具体的场景拿出来具体讨论
    AoEiuV020CN
        4
    AoEiuV020CN  
       2022-06-30 16:09:10 +08:00
    这个 a 永远是这个 A ,确实不用了非要说泄露的话也只泄露一个 A 的空间,这点通常都是无视的,
    想要清理就在确定 a 不再使用之后来个=null 不就完事了,
    Jooooooooo
        5
    Jooooooooo  
       2022-06-30 16:11:09 +08:00
    这个就和 "1 是不是素数" 这个问题有点像

    1 为什么不是素数, 因为素数定义里面说 1 不是, 你若是把 "1 是素数"加到素数的定义里, 那 1 就是素数 (有些人确实会这么定义

    语言由大家赋予含义, 你把你描述的场景叫做"内存泄露", 那它就是(只不过有可能其他人有别的定义

    在这里, 通常的定义下, 你描述的场景不是"内存泄露" (当然又要说, 若是你把它定义成"内存泄露". 那它就是
    banmuyutian
        6
    banmuyutian  
       2022-06-30 16:12:52 +08:00
    你想想 java 进程销毁的时候这个堆还存不存在
    quicksand
        7
    quicksand  
       2022-06-30 16:14:09 +08:00
    public static A a =new A()换成 String A = new String("");我觉得就能得出结论了
    dcsuibian
        8
    dcsuibian  
       2022-06-30 16:21:02 +08:00
    wiki:
    内存泄漏(英语:memory leak )是计算机科学中的一种资源泄漏,主因是计算机程序的内存管理失当,因而失去对一段已分配内存空间的控制,程序继续占用已不再使用的内存空间,或是存储器所存储之对象无法透过执行代码而访问,令内存资源空耗。

    这个对象你仍然可以通过 类.a 访问啊,怎么就内存泄露了。
    moxiaowei
        9
    moxiaowei  
    OP
       2022-06-30 16:21:57 +08:00
    @quicksand 谢谢 我理解了
    cpstar
        10
    cpstar  
       2022-06-30 16:32:15 +08:00
    这是 JVM 的内存机制问题,new A()创建了堆区,把它给 static A ,那么引用计数+1 ,内存回收的时候,看到这个引用>0 的,是不回收的,必然会在内存中一直呆着。这哪能叫内存泄漏,这叫内存占用。
    chtcrack
        11
    chtcrack  
       2022-06-30 16:35:35 +08:00   1
    帮你搜索了一下 java 内存泄漏的文章,建议你去看看..
    https://developer.51cto.com/article/667083.html
    hhjswf
        12
    hhjswf  
       2022-06-30 16:39:13 +08:00
    内存泄漏是该回收而没法回收的。这个堆对象一直都不是回收对象啊
    zmal
        13
    zmal  
       2022-06-30 16:46:26 +08:00
    你写了 a = null ,但 new A() 对象因为某种原因未被 GC ,这才叫内存泄露。
    static 属性作为 GC root ,任何时候都不会被 GC 。
    pursuer
        14
    pursuer  
       2022-06-30 18:48:17 +08:00
    如果 OP 想要做动态申请释放的单例的话,可以看下弱引用
    cheng6563
        15
    cheng6563  
       2022-06-30 19:12:34 +08:00
    内存泄漏指的是你有这么个玩意 public static List<A> a =new ArrayList<A>();
    然后你有些不知道干啥的代码一直往里面加数据,但没有任何代码去取数据或者删数据。
    xFrye
        16
    xFrye  
       2022-06-30 19:20:59 +08:00
    你的类不是一直存在吗,类的生命周期跟静态变量 a 的一样,这没有 memory leak 吧
    yeqizhang
        17
    yeqizhang  
       2022-06-30 19:38:08 +08:00 via Android
    你这种不叫内存泄露,很常见的写法了,到处都有。只是占内存而已,多了顶多会有个“内存溢出”问题
    yeqizhang
        18
    yeqizhang  
       2022-06-30 19:39:53 +08:00 via Android
    @yeqizhang 可能也不叫内存溢出,超出内存有好几种情况
    FrankHB
        19
    FrankHB  
       2022-07-05 03:32:58 +08:00
    @dcsuibian @yeqizhang 这种理解是错的。
    内存泄漏指的是违反资源管理预期表现的行为,可达性判断只是其中的一个保守标准,还有其它种类的 indefinitively lost 。
    理论上,[Cl98] 提出以空间复杂度类描述内存资源泄漏。这是一种涵盖比较完全的分类。在这个意义下,没有 PTC(proper tail call) 泄漏调用栈也是一种泄漏。PTC 以上还有 evlis/sfs(safe for space)等更强的保证,不过静态语言一般会因为要求局部变量静态确定而自动满足 sfs 了。
    实际上,C++ 这样的语言在基本运行时实现中也存能在其它种类的内存泄漏,例如 libstdc++ emergency buffer 会被 valgrind 标记为 lost ;尽管维护者 Jonathon Wakely 缺乏相关了解而拒不承认这是 bug 。
    泄漏并不都是不可接受的,取决于用户和开发者的预期。所以经验上,@Jooooooooo 给出了理论上也能正确的万金油回答。
    但是用户未必那么好说话。所以经常只有应用开发者两头受气了,如果自己没个数下场可能更凄惨。说到这里,再日经鄙视一下:github.com/dart-lang/language/issues/490

    [Cl98]: https://www.researchgate.net/profile/William_Clinger/publication/2728133_Proper_Tail_Recursion_and_Space_Efficiency/links/02e7e53624927461c8000000/Proper-Tail-Recursion-and-Space-Efficiency.pdf
    Aresxue
        20
    Aresxue  
       2022-07-13 15:52:01 +08:00
    这叫内存逃逸。。。看下逃逸分析相关的知识就明白是怎么回事了,内存泄露更多的是一个过程,因为回收不掉导致可用内存随着程序运行越来越少。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2756 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 12:38 PVG 20:38 LAX 04:38 JFK 07:38
    Do have faith in what you're doing.
    ubao msn 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