线程完成后何时释放线程上分配的对象? [关闭]
Posted
技术标签:
【中文标题】线程完成后何时释放线程上分配的对象? [关闭]【英文标题】:When will objects allocated on a thread be freed after the thread completes? [closed] 【发布时间】:2018-04-29 07:22:14 【问题描述】:在这段代码中
new Thread(new Runnable()
@Override
public void run()
byte b[] = new byte[1024*1024*1024];
try
Thread.sleep(5000);
catch (InterruptedException e)
e.printStackTrace();
// just for testing
b = null;
,"thread").start();
5 秒后 1 GB 的内存应该是空闲的! 但它不会!
永远不会!!
我怎样才能找回记忆?
【问题讨论】:
为什么你认为它应该是免费的?它是符合条件的 GC,这并不意味着它很快就会被 GC。您所能做的就是相信 GC 最终会做到这一点。 @AndyTurner 不符合 GC 条件。 @shmosel 正确,但在休眠后,变量被重新分配为 null,删除了对b
的最后引用。 OP 期望它在在睡眠之后立即被释放。
@mehranrafiee 为什么?你想达到什么目标,你想解决什么问题? GC 最终将运行,清理阵列。如果您希望进程将一些堆内存返回给操作系统,那么这也是可能的。一些 GC 可以做到这一点,例如G1 GC,它是 Java 9 中的默认 GC(但也可以在以前的版本中启用)。您可以尝试运行System.gc()
,但这只是一种启发式方法,它可以根据许多事情实现为无操作...
任务管理器不会测量JVM堆,它会测量分配给JVM进程的总内存,这是另一回事。要查看 JVM 堆,请使用 jvisualvm 之类的工具。 jvisualvm 工具可以向您显示堆内分配的对象,您可以使用它向您的 JVM 发送信号,请求它在设置为 null 后删除任何孤立对象,例如您的 b
数组。如果在从 jvisualvm 发送此类信号后的一段时间内,jvisualvm 报告分配的对象占用的空间随着时间的推移继续增长,那么您可能有内存泄漏。
【参考方案1】:
简单的答案是最终:不早也不晚。
您无法直接控制何时收集垃圾。如果实例不再引用它,垃圾收集器会在某个时候清理它。
【讨论】:
就是这样,我想知道GC无法释放内存的连接在哪里 仅在一种情况下 - 当列表中有一个引用仍在使用时。例如,当您在方法中创建对象然后将其返回给调用者时。直到调用者中的引用保持 GC 才能触及内存。这就是为什么有时使用new
并不好,而使用工厂来创建对象是更好的方法。
但在这种情况下,只有一个字节数组,仅此而已!
谁在乎它是什么?它是一个对象,并且有对它的引用。您的问题可能在代码中的某个地方。例如,如果代码将对象放入任何集合(列表、映射、集合)并保留它 - 因此,该集合中存在对它的引用......等等......【参考方案2】:
在 Java 中,您不能显式释放内存。
这取决于 JVM 垃圾收集器设置。 GC 行为有许多参数。
其中一些与一个 JVM 实现和版本不同。
但是,你不需要关心它。当不再引用该对象时,将在 GC 决定该时间时清理内存。
一般来说,当方法完成并且内存可以被 GC 清理时,方法引用中的所有变量都会消失。
您可以建议 GC 运行如下:
...
// just for testing
b = null;
System.gc();
但无论如何这都是一个提示。 GC 可能会运行,也可能不会。
有时像你一样排队
b = null;
不仅有利于测试,而且并不常见。
您可以尝试在 JVM 参数中操纵 GC 设置,以使 GC 更加积极,以避免经常运行 Full GC。
Internet 上有大量资源作为 Oracle JVM 的示例: Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide
记住:不同的JVM可能有不同的GC参数。
【讨论】:
还有一点需要注意:在某些情况下,内存会变成“孤儿”,只能由 Full GC 清除,Full GC 仅在堆大小接近顶部时运行。部分 GC(在方法调用之间)无法选择它。 Full GC 非常昂贵 - 当它运行所有线程时停止并等待它完成。我不记得它的实际案例,但它可能会发生。这是关于创作者在创作之前离开的时间等等......【参考方案3】:在 java 中没有直接释放内存的方法。 GC 将运行并处理此问题。如果你认为你会得到 outofmemoryexception,那么请注意,java 将在抛出该错误之前运行垃圾收集器以释放一些内存。希望这会有所帮助
【讨论】:
你的意思是它会一直保留在内存中,直到其他东西需要内存? no.. GC运行时,内存会被释放......即使没有剩余内存,在抛出OutOfMemoryException之前,Java会运行GC,看看是否可以释放任何东西以上是关于线程完成后何时释放线程上分配的对象? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章