我想知道如何在Java 1.4.2和Java 1.6.0中禁用它,因为我们目前正在测试两个JVM,以确定哪个执行速度更快。
听起来你想要节省时间,但方法不对。禁用垃圾回收所能节省的时间(对于单个任务而言)微不足道,相较于启动和关闭Java进程所需的时间。如果运行时间性能是你的目标,你可以考虑创建一个Java进程,多次请求它执行你需要的工作。
无法完全禁用垃圾回收。当JVM耗尽空间时才会运行垃圾回收,因此您可以为程序分配更多内存。将以下命令行选项添加到Java命令中:
-Xmx256M -Xms256M
这将为程序提供256MB的内存(默认值为64MB)。然而,对于默认大小的JVM,垃圾收集不会花费3秒钟的时间,因此您可能需要更仔细地调查程序正在执行什么操作。Yourkit profiler非常有用,可以帮助找出哪些操作需要较长时间。
只有在JVM内存短缺时,垃圾回收才会触发,所以你要么进行垃圾回收,要么就会程序崩溃。尝试开启详细的垃圾回收并查看是否实际花费了大量时间。
java -verbose:gc
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
没有UnlockExperimentalVMOptions
参数,JVM将无法启动,请确保它已包含。
不幸的是,如果您没有使用Epsilon GC,就没有办法禁用、停止或防止垃圾回收发生。就像不能触发GC一样,您也不能停止Java GC。算法是非确定性的,只有JVM可以控制它们何时发生。
您可以使用-Xmx
选项来设置最大堆大小;使用更大的堆应该可以防止虚拟机过早地耗尽内存并需要进行垃圾收集。
与其他人所说的相反,有一种悬挂垃圾收集器的方法,虽然非常复杂。
如果通过JNI调用本地函数,在本地代码调用GetPrimitiveArrayCritical和ReleasePrimitiveArrayCritical之间,GC将被暂停。这是因为它是用于在Java和本地代码之间共享内存的机制,而GC可能会移动内存中的对象,必须这样做。
因此,要利用此功能,您需要创建一个JNI函数,该函数调用前者,然后轮询写入该临界数组的标志(它可以只是一个byte[1]),等待看到该标志,然后调用后者。当Java代码希望暂停GC时,它将调用JNI方法,当它希望恢复GC时,设置上述标志(我相信对关键数组的读/写是易失性的,因此本地代码将立即看到该标志)。
现在我并不是说这是一个好主意,当然也不是解决OP问题的正确方法。但是,如果您绝对必须暂时暂停GC以某种原因(也许您希望通过sun.misc.Unsafe操纵原始内存,并需要确保在此期间GC不移动对象),那么就可以实现它。
正如大家所说,你不能在JVM中禁用GC,这是有道理的,因为如果可以禁用GC,由于Java没有显式的方式让开发人员删除堆数据,就会导致内存泄漏。
你是否可以访问此Java二进制文件的源代码?如果可以,分析它并查看是否有任何瓶颈可以更好地编写以减少GC活动。这可以使用大多数Java分析器(例如JProbe)完成。