是否有可能在Java中强制垃圾收集,即使这很棘手?我知道System.gc();和Runtime.gc ();但他们只建议做GC。如何强制GC?
当前回答
另一种选择是不创建新对象。
对象池是为了减少Java中对GC的需求。
对象池通常不会比对象创建快(特别是对于轻量级对象),但它比垃圾收集快。如果您创建10,000个对象,每个对象是16个字节。GC需要回收160,000个字节。另一方面,如果您不需要同时使用所有10,000个对象,您可以创建一个池来回收/重用对象,这样就不需要构造新对象,也不需要GC旧对象。
类似这样(未经测试)。 如果你想让它是线程安全的,你可以把LinkedList换成ConcurrentLinkedQueue。
public abstract class Pool<T> {
private int mApproximateSize;
private LinkedList<T> mPool = new LinkedList<>();
public Pool(int approximateSize) {
mApproximateSize = approximateSize;
}
public T attain() {
T item = mPool.poll();
if (item == null) {
item = newInstance();
}
return item;
}
public void release(T item) {
int approxSize = mPool.size(); // not guaranteed accurate
if (approxSize < mApproximateSize) {
recycle(item);
mPool.add(item);
} else if (approxSize > mApproximateSize) {
decommission(mPool.poll());
}
}
public abstract T newInstance();
public abstract void recycle(T item);
public void decommission(T item) { }
}
其他回答
您可以从命令行触发GC。这对于batch/crontab非常有用:
jdk1.7.0/bin/jcmd <pid> GC.run
看到的:
https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html
是的,几乎可以强迫你必须以相同的顺序调用方法,同时这些方法是:
System.gc ();
System.runFinalization ();
即使只是一个对象来清理,同时使用这两个方法强制垃圾收集器使用不可达对象的finalize()方法释放分配的内存并执行finalize()方法的状态。
不过是一个可怕的实践使用垃圾收集器,因为使用它可能会引入一个加载的软件可能甚至比在内存坏,垃圾收集器有自己的线程是不可能控制+根据gc可能需要更多的时间和所使用的算法是考虑非常低效,您应该检查您的软件如果它坏在gc的帮助,因为它绝对是坏,一个好的解决方案不能依赖于gc。
注意:只是要记住,只有在finalize方法中没有对对象进行重赋时,这才会起作用,如果发生这种情况,对象将保持存活,它将有一个复活,这在技术上是可能的。
如何强制Java GC
好了,这里有几种强制Java GC的不同方法。
单击JConsole的Perform GC按钮 使用JMap的JMap -histo:live 7544命令,其中7544是pid 调用Java诊断控制台的jcmd 7544 GC.run命令 调用system . gc ();在代码中 .gc调用Runtime.getRuntime () ();在代码中
这些都不行
这是一个肮脏的小秘密。这些方法都不能保证有效。你真的不能强制Java GC。
Java垃圾收集算法是不确定的,虽然所有这些方法都可以激励JVM执行GC,但实际上不能强制执行。如果JVM有太多事情要做,而停止世界操作是不可能的,那么这些命令要么会出错,要么会运行,但GC实际上不会发生。
if (input.equalsIgnoreCase("gc")) {
System.gc();
result = "Just some GC.";
}
if (input.equalsIgnoreCase("runtime")) {
Runtime.getRuntime().gc();
result = "Just some more GC.";
}
解决恼人的问题
如果遇到内存泄漏或对象分配问题,请修复它。坐在那里,手指放在Java任务控制的强制Java GC按钮上,只会拖延时间。使用Java Flight Recorder配置应用程序,在VisualVM或JMC中查看结果,并修复问题。试图强制Java GC是一个愚蠢的游戏。
如果需要强制垃圾收集,也许应该考虑如何管理资源。您正在创建持久化在内存中的大对象吗?您是否正在创建具有Disposable接口的大型对象(例如图形类),并且在使用它时不调用dispose() ?您是否在类级别声明了只需要在单个方法中使用的东西?
JVM规范没有详细说明垃圾收集。因此,供应商可以自由地以自己的方式实现GC。
因此,这种模糊性导致了垃圾收集行为的不确定性。您应该检查JVM的详细信息以了解垃圾收集方法/算法。此外,还有自定义行为的选项。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap