2015-04-23 77 views
1

我在公开可用的地图中保留对本地创建的对象的引用。当我从地图中删除对象时,它也应该从内存中删除(无效)。如何从地图中删除对象/实例后从内存中删除?

public class X { 
    public boolean infiniteloop = true; 

    public X() { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while (infiniteloop) { 
        System.out.println("Still exists"); 
       } 
      } 
     }).start(); 
    } 


public class Y{ 
     Map myMap = new HashMap(); 
     public Y() throws InterruptedException{ 
     X x = new X(); 
     myMap.put("Key", x); 
     Thread.sleep(10000); 
     ((X)myMap.get("Key")).infiniteloop= false; 
     myMap.remove("Key"); 
     } 
} 

在上面的代码中,“仍然存在”是在myMap.remove(“Key”)之后进行的。这意味着对象仍然存在于内存中。我如何从内存中删除它?

+0

'Runnable'不关心它是否在地图中。 –

+1

runnable不是我认为的问题,因为我在将地图中的对象从地图中移除之前将inifiniteloop设置为false。 – MeesterPatat

+0

不,您将其设置为false,'Thread'已经运行。你可以简单地用调试器检查它。 –

回答

2

Java负责在最佳时刻从内存中删除对象,所以不用担心。如果确实要确保线程已终止,则应保留对Thread和或Runnable的引用,以便您可以尝试正常关闭线程(并在必要时突然中断)。

如果你想尝试从内存中删除对象尽快与您可以尝试System.gc()你可以尝试的System.gc(),但被认为是bad practice

有可能涉及到使用涉及父实例变量一些挂羊头卖狗肉这使得线程不会终止,但有人比我更聪明可以肯定地解释:)

+0

我不认为线程是问题,因为当我将inifiniteloop设置为false时,线程在完成后终止。但是对象x仍然存在于内存中。 – MeesterPatat

+0

我已经更新了我的答案,再看一次。 – wonderb0lt

+0

X类表示蓝牙信标。我的(Android)应用程序为范围内的每个信标生成一个对象,并保留对地图中所有信标对象的引用。当信标不在范围内时,我想从地图和内存中完全删除它,以避免内存中有很多信标对象,但它们不在范围内。这积累非常快。所以从内存中删除对象很重要。 gc需要多长时间才能确定该物体不再需要,并将其移除? – MeesterPatat

2

你只是从地图中删除你的对象使用remove,但该对象仍然存在。 JVM将垃圾如果没有对它的引用,自动收集你的对象。您需要设置x=null以使X对象符合GC要求。 这将删除对象的引用。

另外,请记住GC过程不是即时的。这不是确定性的。它在JVM中的单独线程上运行。

设置x = null将删除原始对象的引用。然后该对象有资格使用GC。此外,该对象已从地图中移除,因此对地图内对象的任何引用也都不存在。

如果您的对象没有得到GC'ed,请确保在其余代码中没有对该对象的引用。你只提供了伪代码,我认为你应该搜索更广泛的问题

+0

但是,如何将x从地图设置为null?我不想在地图之外继续引用类X,因为一次有多个x的实例。当我从地图中删除对象时,我不再需要它,并想从内存中删除它。 – MeesterPatat

+0

我建议,并得到downvoted遗忘,我也100%肯定它不会收集和泄漏,如果其他繁忙的线程有更高的优先级... – Palcente

+0

不会从地图得到的价值只是使副本目的? – MeesterPatat

1

正在运行的线程没有看到infiniteloop变量已被更改。 要使此更改可见,您需要添加一些同步。例如,将该变量标记为volatile

public volatile boolean infiniteloop = true; 

现在它应该工作。没有必要做更多的事情,没有x=null和东西。 要了解更多信息,请阅读Java Memory Model

+0

因此,如果我使inifiniteloop volatile并将其设置为false,则线程会终止,如果我从映射中删除对象x,它会立即自动从内存中移除因为我的应用程序中没有提及它? – MeesterPatat

+0

@MeesterPatat这是正确的,除了一件事:没有保证它会被删除_immediately_,但它肯定会被_eligible_进一步的GC。 –

+0

没有办法立即将其删除吗? Wonderb0lt建议System.gc(),但这是一个不好的做法。 – MeesterPatat