是否有可能在Java中强制垃圾收集,即使这很棘手?我知道System.gc();和Runtime.gc ();但他们只建议做GC。如何强制GC?
当前回答
jlibs库有一个很好的用于垃圾收集的实用程序类。您可以使用WeakReference对象的一个漂亮的小技巧强制垃圾收集。
RuntimeUtil.gc()从jlibs:
/**
* This method guarantees that garbage collection is
* done unlike <code>{@link System#gc()}</code>
*/
public static void gc() {
Object obj = new Object();
WeakReference ref = new WeakReference<Object>(obj);
obj = null;
while(ref.get() != null) {
System.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) { }
}
FYI
方法调用System.runFinalizersOnExit(true)保证终结器方法 在Java关闭之前调用。然而,这种方法本质上是不安全的 并且已经被弃用。另一种方法是在方法中添加“关机钩子” Runtime.addShutdownHook。
马萨拉特·西迪基
如果您正在使用JUnit和Spring,请尝试在每个测试类中添加以下内容:
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
在OutOfMemoryError的文档中,它声明除非虚拟机在完整的垃圾回收后未能回收内存,否则它不会被抛出。因此,如果您一直分配内存直到出现错误,那么您将已经强制进行完整的垃圾收集。
想必您真正想问的问题是“如何回收我认为应该通过垃圾收集回收的内存?”
手动请求GC(不是从System.gc()):
转到:bin文件夹在JDK中,例如。c: \ Program Files \ Java \ jdk1.6.0_31 \ bin 打开jconsole.exe 连接到所需的本地进程。 进入“内存”页签,单击“执行GC”。
推荐文章
- 在流中使用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