是否有可能在Java中强制垃圾收集,即使这很棘手?我知道System.gc();和Runtime.gc ();但他们只建议做GC。如何强制GC?
当前回答
I did some experimentation (see https://github.com/mikenakis/ForcingTheJvmToGarbageCollect) trying about a dozen different ways of performing a garbage collection, including ways described in this answer, and more, and I found that there is absolutely no frigging way to deterministically force the JVM to do a complete garbage collection. Even the best answers to this question are only partially successful in that the best they achieve is some garbage collection, but never a guaranteed full garbage collection.
我的实验表明,下面的代码片段产生了最好的(最不坏的)结果:
public static void ForceGarbageCollection()
{
long freeMemory = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed();
for( ; ; )
{
Runtime.getRuntime().gc();
Runtime.getRuntime().runFinalization();
long newFreeMemory = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed();
if( newFreeMemory == freeMemory )
break;
freeMemory = newFreeMemory;
sleep( 10 );
}
}
其中sleep()函数如下:
private static void sleep( int milliseconds )
{
try
{
Thread.sleep( milliseconds );
}
catch( InterruptedException e )
{
throw new RuntimeException( e );
}
}
不幸的是,睡眠中的数字10是有魔力的;它假设您每秒执行中等数量的内存分配,这将导致中等数量的结束。如果你通过对象的速度更快,那么10可能是不够的,你可能需要等待更长的时间。您可以将其设置为100,但无论您将其设置为多少,总有可能它不够用。
话虽如此,在一个受控制的环境中,10个就足够了,这种方法被观察到可以持续地从内存中消除所有不可访问的对象,而本问答中提到的其他方法都不能做到这一点。我在github上链接的实验代码证明了这一点。
在我看来,Java虚拟机没有提供执行强制的、无条件的、确定的、绝对彻底的、让世界停止的垃圾收集的方法,这一事实使它崩溃了。
换句话说,JVM的创造者是如此傲慢,以至于认为他们比我们更了解我们是否想要这样做,或者我们是否应该这样做。别那么傲慢。如果某些东西像魔法一样起作用,那么必须提供一些绕过魔法的方法。
其他回答
真的,我不懂你。而是成为 清楚“无限物体创造” 我是说有一些 代码在我的大系统做创建 可以处理的对象,并在其中生活 回忆,我无法得到这一片 其实是代码,只是个手势!!
这是正确的,唯一的姿态。你已经有了很多标准答案。让我们一个一个来看:
我无法得到这段代码 实际上
正确,没有真正的jvm——这只是一个规范,一堆描述期望行为的计算机科学…我最近研究了如何从本地代码初始化Java对象。要得到你想要的东西,唯一的方法就是执行所谓的主动置空。如果做错了,错误是非常糟糕的,我们必须将自己限制在问题的原始范围内:
我大系统里的一段代码 创建对象
这里的大多数海报会假设你说你正在处理一个界面,如果是这样的话,我们就必须看看你是一次被交付整个对象还是一个项目。
如果你不再需要一个对象,你可以将null赋值给该对象,但如果你弄错了,就会生成一个空指针异常。我敢打赌,如果您使用NIO,您可以实现更好的工作
任何时候你或我或其他人得到:“拜托,我非常需要那个。”这几乎是一个普遍的前兆,几乎完全破坏你正在努力工作....写一个小的示例代码,从它消毒任何实际使用的代码,并向我们展示您的问题。
不要沮丧。通常情况下,这意味着您的dba正在使用从某个地方购买的包,并且原始设计没有针对大规模数据结构进行调整。
这很常见。
强制GC的最佳(如果不是唯一)方法是编写自定义JVM。我认为垃圾收集器是可插拔的,因此您可能只需要选择一个可用的实现并对其进行调整。
注意:这不是一个简单的答案。
最好的选择是调用System.gc(),这只是给垃圾收集器一个提示,表明您希望它进行收集。由于垃圾收集器是不确定的,因此没有办法强制和立即回收。
如果您正在运行内存并得到一个OutOfMemoryException,您可以尝试通过java -Xms128m -Xmx512m开始编程来增加java可用的堆空间的数量,而不仅仅是java。这将使您的初始堆大小为128Mb,最大堆大小为512Mb,远远超过标准的32Mb/128Mb。
手动请求GC(不是从System.gc()):
转到:bin文件夹在JDK中,例如。c: \ Program Files \ Java \ jdk1.6.0_31 \ bin 打开jconsole.exe 连接到所需的本地进程。 进入“内存”页签,单击“执行GC”。
推荐文章
- 如果我同步了同一个类上的两个方法,它们能同时运行吗?
- 如何减去X天从一个日期对象在Java?
- Java标识符中的“连接字符”是什么?
- 一对多、多对一、多对多的区别?
- 从枚举中选择一个随机值?
- 如何从URL获取参数与JSP
- 如何在Eclipse中生成Javadoc注释?
- 找到java类从哪里加载
- 从集合中随机选取一个元素
- 为什么x == (x = y)和(x = y) == x不一样?
- 什么Java 8流。收集等价物可在标准Kotlin库?
- 等待未来的名单
- 如何检查JSON键是否存在?
- 为什么MongoDB Java驱动在条件中使用随机数生成器?
- 即使从未抛出异常,使用try-catch块的代价是否昂贵?