【问题标题】:Does not storing a newly declared object cause a memory leak?不存储新声明的对象会导致内存泄漏吗?
【发布时间】:2022-01-20 08:43:50
【问题描述】:

我的意思是通过帖子标题说 - 这样做:

public static void makeNewObjectAndDoTask() {
    new SomeClass().doYourTask();
}

我自己用 Java 和 JavaScript 等语言编写了这样的代码 - 声明一个新对象而不将其存储在变量中,只需调用其方法之一。这会导致内存泄漏吗? ..或者对象是否在方法堆栈的末尾被清除/被 Java 垃圾收集器释放?

为了安全,我应该这样做吗?:

public static void makeNewObjectAndDoTask() {
    SomeClass obj = new SomeClass().doYourTask();
    obj = null;
    //System.gc(); // Perhaps also call the collector manually?
}

【问题讨论】:

  • 看不到内存泄漏。
  • “对象 [...] 是否被 Java 垃圾收集器释放?”是的

标签: java memory-leaks java-memory-leaks


【解决方案1】:

正如评论者已经回答的那样,代码中没有内存泄漏

public static void makeNewObjectAndDoTask() {
    new SomeClass().doYourTask();
}

至少就其本身而言,假设 SomeClass() 构造函数和 doYourTask() 方法不会造成内存泄漏。

毫无疑问,垃圾收集器会在未来某个时间清理 SomeClass 实例。

它是如何工作的?

  • 不再从程序代码访问的实例将被垃圾回收。可访问性意味着在变量、字段、数组元素、方法参数等中被引用。
  • 一旦new SomeClass().doYourTask(); 语句完成,就无法再访问这个单独的SomeClass 实例。因此,它满足垃圾收集标准。
  • 下次垃圾收集器运行时,它可以回收实例占用的内存(及其字段,递归,只要它们没有在其他地方引用)。

替代代码

public static void makeNewObjectAndDoTask() {
    SomeClass obj = new SomeClass().doYourTask();
    obj = null;
}

只会延迟垃圾收集机会,因为它会将引用存储在 obj 中,从而使实例可以在至少一小段额外时间内访问,直到您分配 obj = null;

System.gc(); 中手动调用垃圾收集器很少是一个好主意。它强制 GC 运行(并将执行时间花在清理内存上),而不是依赖 JVM 高度优化的 GC 调度策略。除非您对垃圾收集器有透彻的了解,否则不要这样做,这会导致您得出 GC 策略在您的情况下失败的结论。

我们不希望出现OutOfMemoryErrors,也不希望浪费过多的时间用于垃圾回收,标准的GC系统在这两方面都做得非常好。

【讨论】:

  • 明白了,谢谢!~
猜你喜欢
  • 2012-11-04
  • 2015-08-22
  • 2022-06-13
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
  • 2021-09-25
  • 2014-12-08
相关资源
最近更新 更多