从内存中删除一个变量

8

我有三个数组变量 a[dynamic], b[dynamic], c[dynamic],它们的大小可以任意。我想要销毁其中一个变量(比如说a),因为我不再需要这个变量了。


1
你为什么想要这样做?你了解垃圾回收器的作用吗? - Andres F.
我猜你正在从C语言转向Java! - Eric C.
是的,我在这方面相当擅长。实际上,变量只有在其生命周期结束时才会被销毁。 - special
@Eric:不是那样,我需要知道是否有任何方法可以减少占用的内存。就这样。 - special
3个回答

23

您可以通过将null赋值给数组来告诉垃圾收集器可以释放它:

    int[] a = new int[someSize];
    int[] b = new int[someSize];
    ....
    // I no longer need 'a'
    a = null;
    // ... but I can still use 'b'

然而,有一些需要注意的事项:

  • 这并不会释放空间。相反,它使数组有资格被垃圾收集器释放。GC可能需要很长时间才能释放它。

  • 实际上,只有当数组不可达时,它才有资格进行垃圾回收。如果您已将对数组的引用分配给另一个(仍然活动的)局部变量、可达对象的字段等,则GC不会回收它。

  • 在现实的Java应用程序中,很少有这样做(清空变量)的必要。通常的做法是让变量在正常计算过程中超出范围1。只有在变量不会很快超出范围且它引用了大型数组/对象或网络时,才会显式地将变量(或对象字段或数组元素)设置为null

  • 在将null赋值后调用System.gc()来强制运行GC是极不明智的...永远都是如此2。如果调用有任何影响,那么它很可能是昂贵的。最好让JVM在最佳时间安排GC。


1 - 任何合理的JVM实现都知道当方法退出时局部变量会超出范围。 JVM是否以更细粒度跟踪作用域是实现特定的,而且(说实话)我不知道JVM在实践中如何处理这个问题。

请注意,几乎任何东西在技术上都符合JLS要求...只要GC不删除可达(即非垃圾)对象。这包括使用Epsilon无操作GC的JVM,该GC从不收集垃圾并在空间耗尽时终止JVM。

2 - 唯一合法的原因是:1)测试与GC相关的功能的行为;例如,finalizers,引用队列处理器等,或2)避免实时应用程序中有害的GC暂停;例如,在实时游戏中更改“级别”时运行GC。


1

Stephen C已经回答了你的问题,但是对于非原始类型,如果你不需要它,你也需要确保数组中的所有对象都被标记为null,这将确保你没有内存泄漏。

像这样:

for(Object obj : myObjectArray){
  obj = null;
}

然后将您的数组引用设为 null。
myObjectArray = null;

1
在引用数组为null之后,所有的数组索引都变得无法访问。先将它们设为null没有影响。现在,可能存在对数组或其索引的其他引用,但这是一个独立的问题,与此无关。 - entonio
@entonio - 同意。在大多数情况下,置空是不必要的,如果不必要,则浪费CPU周期。此外,总有可能会错误地过早或过于积极地“null”事物。在我看来,最好不要这样做...除非您有充分的理由相信不置空导致显着的内存泄漏。 - Stephen C

-1

从ArrayList中删除所有元素

arrayList.removeAll(arrayList);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接