如何在 Java 中强制垃圾收集?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1481178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to force garbage collection in Java?
提问by
Is it possible to force garbage collection in Java, even if it is tricky to do? I know about System.gc();
and Runtime.gc();
but they only suggest to do GC. How can I force GC?
是否可以在 Java 中强制进行垃圾回收,即使这很棘手?我知道System.gc();
,Runtime.gc();
但他们只建议做 GC。我怎样才能强制GC?
回答by Andrew Hare
Your best option is to call System.gc()
which simply is a hint to the garbage collector that you want it to do a collection. There is no way to forceand immediate collection though as the garbage collector is non-deterministic.
您最好的选择是调用System.gc()
which 只是暗示垃圾收集器您希望它进行收集。尽管垃圾收集器是不确定的,但无法强制立即收集。
回答by Paul Lammertsma
It would be better if you would describe the reason why you need garbage collection. If you are using SWT, you can dispose resources such as Image
and Font
to free memory. For instance:
如果您能描述需要垃圾收集的原因会更好。如果您正在使用 SWT,您可以处理诸如Image
和 之类的资源Font
以释放内存。例如:
Image img = new Image(Display.getDefault(), 16, 16);
img.dispose();
There are also tools to determine undisposed resources.
还有一些工具可以确定未处置的资源。
回答by Bob Kaufman
If you need to force garbage collection, perhaps you should consider how you're managing resources. Are you creating large objects that persist in memory? Are you creating large objects (e.g., graphics classes) that have a Disposable
interface and not calling dispose()
when done with it? Are you declaring something at a class level that you only need within a single method?
如果您需要强制垃圾收集,也许您应该考虑如何管理资源。您是否正在创建持久存在于内存中的大型对象?您是否正在创建具有Disposable
接口且dispose()
在完成后不调用的大型对象(例如,图形类)?您是否在类级别声明了您只需要在单个方法中的内容?
回答by Pete Kirkham
Under the documentation for OutOfMemoryErrorit declares that it will not be thrown unless the VM has failed to reclaim memory following a full garbage collection. So if you keep allocating memory until you get the error, you will have already forced a full garbage collection.
根据OutOfMemoryError的文档,它声明它不会被抛出,除非 VM 在完全垃圾收集后未能回收内存。因此,如果您一直分配内存直到出现错误,您就已经强制进行了完整的垃圾回收。
Presumably the question you really wanted to ask was "how can I reclaim the memory I think I should be reclaiming by garbage collection?"
想必您真正想问的问题是“如何回收我认为应该通过垃圾收集回收的内存?”
回答by Nicholas Jordan
.gc is a candidate for elimination in future releases - a Sun Engineer once commented that maybe fewer than twenty people in the world actually know how to use .gc() - I did some work last night for a few hours on a central / critical data-structure using SecureRandom generated data, at somewhere just past 40,000 objects the vm would slow down as though it had run out of pointers. Clearly it was choking down on 16-bit pointer tables and exhibited classic "failing machinery" behavior.
.gc 是未来版本中淘汰的候选者——一位 Sun 工程师曾评论说,世界上可能只有不到 20 人真正知道如何使用 .gc()——我昨晚在中央/关键上做了几个小时的工作数据结构使用 SecureRandom 生成的数据,在刚刚超过 40,000 个对象的某个地方,vm 会变慢,好像它已经用完了指针。很明显,它在 16 位指针表上窒息,并表现出经典的“故障机器”行为。
I tried -Xms and so on, kept bit twiddling until it would run to about 57,xxx something. Then it would run gc going from say 57,127 to 57,128 after a gc() - at about the pace of code-bloat at camp Easy Money.
我试过 -Xms 等等,一直在玩,直到它运行到大约 57,xxx 为止。然后它会在 gc() 之后运行从 57,127 到 57,128 的 gc - 大约是 Easy Money 营地代码膨胀的速度。
Your design needs fundamental re-work, probably a sliding window approach.
您的设计需要基本的返工,可能是滑动窗口方法。
回答by Mainguy
The best (if not only) way to force a GC would be to write a custom JVM. I believe the Garbage collectors are pluggable so you could probably just pick one of the available implementations and tweak it.
强制 GC 的最佳(如果不是唯一)方法是编写自定义 JVM。我相信垃圾收集器是可插拔的,因此您可能只需选择一种可用的实现并对其进行调整。
Note: This is NOT an easy answer.
注意:这不是一个简单的答案。
回答by Nicholas Jordan
Really, I don't get you. But to be clear about "Infinite Object Creation" I meant that there is some piece of code at my big system do creation of objects whom handles and alive in memory, I could not get this piece of code actually, just gesture!!
真的,我不明白你。但是要明确“无限对象创建”,我的意思是我的大系统中有一些代码可以创建处理并在内存中存活的对象,我实际上无法获得这段代码,只是手势!
This is correct, only gesture. You have pretty much the standard answers already given by several posters. Let's take this one by one:
这是正确的,只是手势。你已经得到了几张海报已经给出的标准答案。让我们一项一项:
- I could not get this piece of code actually
- 我实际上无法获得这段代码
Correct, there is no actual jvm - such is only a specification, a bunch of computer science describing a desired behaviour ... I recently dug into initializing Java objects from native code. To get what you want, the only way is to do what is called aggressive nulling. The mistakes if done wrong are so bad doing that we have to limit ourselves to the original scope of the question:
正确,没有实际的 jvm - 这只是一个规范,一堆描述所需行为的计算机科学......我最近研究了从本机代码初始化 Java 对象。为了得到你想要的,唯一的方法就是做所谓的积极归零。如果做错了错误是非常糟糕的,我们不得不将自己限制在问题的原始范围内:
- some piece of code at my big system do creation of objects
- 我的大系统中的一些代码创建了对象
Most of the posters here will assume you are saying you are working to an interface, if such we would have to see if you are being handed the entire object or one item at a time.
这里的大多数海报都会假设你是在说你正在处理一个界面,如果是这样,我们将不得不看看你是被递给整个对象还是一次一个项目。
If you no longer need an object, you can assign null to the object but if you get it wrong there is a null pointer exception generated. I bet you can achieve better work if you use NIO
如果您不再需要一个对象,您可以将 null 分配给该对象,但如果您弄错了,则会生成一个空指针异常。我敢打赌,如果您使用 NIO,您可以获得更好的工作
Any time you or I or anyone else gets: "Please I need that horribly." it is almost universal precursor to near total destruction of what you are trying to work on .... write us a small sample code, sanitizing from it any actual code used and show us your question.
任何时候你或我或其他任何人得到:“拜托,我非常需要它。”这几乎是几乎完全破坏你正在尝试的工作的普遍先兆......给我们写一个小示例代码,从中清除任何使用的实际代码并向我们展示您的问题。
Do not get frustrated. Often what this resolves to is your dba is using a package bought somewhere and the original design is not tweaked for massive data structures.
不要沮丧。通常,这会导致您的 dba 使用从某处购买的软件包,而原始设计并未针对大量数据结构进行调整。
That is very common.
这是很常见的。
回答by Viktor Dahl
If you are running out of memory and getting an OutOfMemoryException
you can try increasing the amount of heap space available to java by starting you program with java -Xms128m -Xmx512m
instead of just java
. This will give you an initial heap size of 128Mb and a maximum of 512Mb, which is far more than the standard 32Mb/128Mb.
如果您的内存不足并获得了一个,OutOfMemoryException
您可以尝试通过启动您的程序来增加 Java 可用的堆空间量,java -Xms128m -Xmx512m
而不仅仅是java
. 这将为您提供 128Mb 的初始堆大小和最大 512Mb,远远超过标准的 32Mb/128Mb。
回答by shams
The jlibs library has a good utility class for garbage collection. You can force garbage collection using a nifty little trick with WeakReferenceobjects.
该jlibs库中有垃圾收集一个很好的实用工具类。你可以使用WeakReference对象的一个小技巧来强制垃圾回收。
RuntimeUtil.gc()from the jlibs:
来自 jlibs 的RuntimeUtil.gc():
/**
* 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();
}
}
回答by rai.skumar
JVM specification doesn't say anything specific about garbage collection. Due to this, vendors are free to implement GC in their way.
JVM 规范没有说明任何关于垃圾收集的具体内容。因此,供应商可以自由地以他们的方式实现 GC。
So this vagueness causes uncertainty in garbage collection behavior. You should check your JVM details to know about the garbage collection approaches/algorithms. Also there are options to customize behavior as well.
所以这种模糊性导致垃圾收集行为的不确定性。您应该检查您的 JVM 详细信息以了解垃圾收集方法/算法。还有一些选项可以自定义行为。