是否有可能在Java中强制垃圾收集,即使这很棘手?我知道System.gc();和Runtime.gc ();但他们只建议做GC。如何强制GC?
当前回答
您可以从命令行触发GC。这对于batch/crontab非常有用:
jdk1.7.0/bin/jcmd <pid> GC.run
看到的:
https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html
其他回答
强制GC的最佳(如果不是唯一)方法是编写自定义JVM。我认为垃圾收集器是可插拔的,因此您可能只需要选择一个可用的实现并对其进行调整。
注意:这不是一个简单的答案。
如果您正在运行内存并得到一个OutOfMemoryException,您可以尝试通过java -Xms128m -Xmx512m开始编程来增加java可用的堆空间的数量,而不仅仅是java。这将使您的初始堆大小为128Mb,最大堆大小为512Mb,远远超过标准的32Mb/128Mb。
在带有G1 GC的OracleJDK 10上,对System.gc()的单个调用将导致GC清理旧集合。我不确定GC是否立即运行。但是,即使在循环中多次调用System.gc(), GC也不会清理Young Collection。为了让GC清理Young Collection,你必须在一个循环中分配(例如new byte[1024]),而不调用System.gc()。出于某种原因调用System.gc()会阻止GC清理Young Collection。
另一种选择是不创建新对象。
对象池是为了减少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) { }
}
最好的选择是调用System.gc(),这只是给垃圾收集器一个提示,表明您希望它进行收集。由于垃圾收集器是不确定的,因此没有办法强制和立即回收。
推荐文章
- 如何添加JTable在JPanel与空布局?
- Statement和PreparedStatement的区别
- 为什么不能在Java中扩展注释?
- 在Java中使用UUID的最重要位的碰撞可能性
- 转换列表的最佳方法:map还是foreach?
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?