我在许多线程中都读过,不可能在Sun的JVM上关闭垃圾回收。但是,出于我们研究项目的目的,我们需要这个功能。任何人都可以推荐一个没有垃圾收集或允许关闭它的JVM实现吗?谢谢。
答案 0 :(得分:15)
我想找到一种快速的方法来将所有对象保存在内存中,以便进行简单的初始概念验证。
执行此操作的简单方法是使用非常大的堆运行JVM,以至于GC永远不需要运行。将-Xmx
和 -Xms
选项设置为较大的值,然后启用GC日志记录以确认GC在测试期间未运行。
这比修改JVM更快,更直接。
(事后看来,这可能行不通。我模糊地回忆起看到的证据表明JVM并不总是尊重-Xms
设置,特别是如果它真的很大不过,在尝试一些更难的方法之前,这种方法值得尝试......比如修改JVM。)
此外,对于你实际想要达到的目标而言,这一切都让我感到不必要(甚至适得其反)。 GC不会丢弃对象,除非它们是垃圾。如果它们是垃圾,你将无法使用它们。 GC禁用/取消的系统的性能并不能说明真实的应用程序将如何执行。
答案 1 :(得分:8)
根据您的需要,这可能有用:
使用-Xbootclasspath选项,您可以指定自己的API类实现。然后,您可以覆盖Object的实现,并向构造函数添加globalList.add(this)
以防止对象被垃圾回收。这肯定是一个黑客,但对于简单的案例研究,它可能就足够了。
另一种选择是采用开源jvm并注释掉启动垃圾收集的部分。我猜它并不复杂。
答案 2 :(得分:4)
Sun的JVM没有这样的选择。 AFAIK,没有其他JVM也有此选项。
您没有说明您正在尝试实现的目标,但您有以下两种选择之一:使用分析器并确切了解GC正在做什么,这样您就可以考虑其影响。另一种是从源代码编译其中一个JVM,并从那里禁用GC。
答案 3 :(得分:1)
也许您可以尝试使VM的可用内存足以让GC永远无法运行。
我的(尽管有限)经验让我建议默认情况下,VM非常懒惰且非常不愿意运行GC。
给予-Xmx 16384M(或其他一些)并确保您的研究对象远远低于该限制,可能会为您提供您希望获得的环境,尽管如此,它显然不会得到保证。
答案 4 :(得分:1)
您是否可以获得开源JVM并禁用其GC,例如Sun's Hotspot?
如果没有垃圾收集,你会期望像这样的代码的语义?
public myClass {
public void aMethod() {
String text = new String("xyz");
}
}
如果没有GC,任何新建的项目和堆栈作用域参考都无法回收。即使你自己的类决定不使用这样的局部变量,或者只使用原始类型,我也看不到你如何安全地使用任何标准Java库。
我有兴趣了解有关您的使用方案的更多信息。
答案 5 :(得分:1)
看看Oracle's JRockit JVM。我已经在使用此JVM的英特尔硬件上看到了非常好的接近确定性的性能,您可以使用Mission Control实用程序来刺激和戳戳运行时,以查看它的执行情况。
虽然您无法完全关闭GC,但我相信您可以使用-Xnoclassgc选项来禁用类的集合。可以将GC调整为minimize latency,但代价是不会增加内存消耗。如果您走这条路线,您可能需要许可证才能将延迟降低到所需的最低值。
还有一个JRockit JVM的实时版本可用,但我认为没有可用的免费开发版本。
答案 6 :(得分:1)
如果GC实际上不需要,你只能关闭它(否则你的应用程序会耗尽内存),如果你不需要GC,它就不应该运行。
最简单的选择是不丢弃任何对象,这将避免执行GC(并设置最大内存非常高,因此您不会用完)。
您可能会发现启动时会获得GC,并且在运行时可能会考虑使用无GC。
答案 7 :(得分:1)
实际上存在暂时停止GC的脏黑客攻击。首先在Java中创建一个虚拟数组。然后,在JNI中,使用GetPrimitiveArrayCritical函数来获取指向数组的指针。 Sun JVM将禁用GC以确保永远不会移动数组并且指针保持有效。要重新启用GC,可以在指针上调用ReleasePrimitiveArrayCritical函数。但这是非常具体的实现,因为其他VM impl可能会固定对象而不是完全禁用GC。 (已经过测试,适用于Oracle Jdk 7& 8)
答案 8 :(得分:1)
这个问题已经过时了,但对于那些可能感兴趣的人来说,有一个建议
开发一个仅处理内存分配的GC,但不实现任何实际的内存回收机制。一旦可用的Java堆耗尽,就执行有序的JVM关闭。
JEP draft: Epsilon GC: The Arbitrarily Low Overhead Garbage (Non-)Collector
答案 9 :(得分:0)
如果我遇到这个问题,我会得到IBM的Jikes Research Virtual Machine,因为:
你不能永远关闭GC,因为Java程序做分配并最终你的内存不足,但很有可能你可以在实验期间延迟GC告诉JVM在堆变得非常大之前不要开始收集。 (这个技巧也可能适用于其他JVM,但我不知道在哪里找到旋钮开始旋转。)