繁体   English   中英

没有垃圾回收的JVM

[英]JVM with no garbage collection

我在很多线程中都读过,不可能在Sun的JVM上关闭垃圾回收。 但是,出于我们研究项目的目的,我们需要这个功能。 任何人都可以推荐一个没有垃圾收集或允许关闭它的JVM实现吗? 谢谢。

我想找到一种快速的方法来将所有对象保存在内存中,以获得简单的初始概念证明。

执行此操作的简单方法是使用非常大的堆运行JVM,以至于GC永远不需要运行。 -Xmx -Xms选项设置为较大的值,并打开GC日志记录以确认GC在测试期间未运行。

这比修改JVM更快,更直接。


(事后看来,这可能不起作用。我模糊地回忆起看到的证据表明JVM并不总是尊重-Xms设置,特别是如果它真的很大。但是,这种方法在尝试一些更难的方法之前值得尝试。 ..比如修改JVM。)

而且,对于你实际想要达到的目标而言,这一切对我来说都是不必要的(甚至适得其反)。 GC不会丢弃对象,除非它们是垃圾。 如果它们是垃圾,你将无法使用它们。 具有GC禁用/否定的系统的性能不会指示真实应用程序将如何执行。

根据您的需要,这可能会起作用:

使用-Xbootclasspath选项,您可以指定自己的API类实现。 然后,您可以例如覆盖Object的实现,并向构造函数添加globalList.add(this)以防止对象被垃圾回收。 这肯定是一个黑客,但对于简单的案例研究,它可能已经足够了。

另一个选择是采用开源jvm并注释掉启动垃圾收集的部分。 我猜它并不复杂。

Sun的JVM没有这样的选择。 AFAIK,没有其他JVM也有此选项。

您没有说明您正在尝试实现的目标,但您有两种选择之一:使用分析器并确切了解GC正在做什么,这样您就可以考虑其影响。 另一种是从源代码编译其中一个JVM,并从那里禁用GC。

实际上存在暂时停止GC的脏黑客攻击。 首先在Java中创建一个虚拟数组。 然后,在JNI中,使用GetPrimitiveArrayCritical函数来获取指向数组的指针。 Sun JVM将禁用GC以确保永远不会移动数组并且指针保持有效。 要重新启用GC,可以在指针上调用ReleasePrimitiveArrayCritical函数。 但这是非常具体的实现,因为其他VM impl可能会固定对象而不是完全禁用GC。 (经测试可用于Oracle Jdk 7和8)

也许您可以尝试使VM的可用内存足以让GC永远无法运行。

我的(尽管有限)经验使我建议默认情况下,VM非常懒惰并且非常不愿意运行GC。

给-Xmx 16384M(或其他一些)并确保你的研究对象远远低于这个限制,可能会给你你想要获得的环境,尽管如此,它显然不会得到保证。

你能获得一个开源JVM并禁用它的GC,例如Sun的Hotspot吗?

如果没有垃圾收集,你会期望像这样的代码的语义?

public myClass {

      public void aMethod() {

            String text = new String("xyz");

      }

}

在没有GC的情况下,任何新建的项目和堆栈范围的引用都无法回收。 即使你自己的类决定不使用这样的局部变量,或者只使用原始类型,我也看不到你如何安全地使用任何标准Java库。

我有兴趣了解有关您的使用场景的更多信息。

看看Oracle的JRockit JVM 我已经在使用此JVM的英特尔硬件上看到了非常好的接近确定性的性能,您可以使用任务控制实用程序来刺激和戳戳运行时,以查看它的执行情况。

虽然您无法完全关闭GC,但我相信您可以使用-Xnoclassgc选项来禁用类的集合。 可以调整GC以最小化延迟 ,但代价是留下内存消耗增长。 如果您要使用此路线,您可能需要许可证才能将延迟降低到所需的最低水平。

还有一个可用的JRockit JVM的实时版本,但我认为没有可用的免费开发人员版本。

你只能关闭GC,如果它实际上不需要(否则你的应用程序将耗尽内存),如果你不需要GC,它不应该运行。

最简单的选择是不丢弃任何对象,这将避免执行GC(并设置最大内存非常高,因此您不会用完)。

您可能会发现在启动时获得GC,并且在运行时可以考虑使用无GC。

问题是陈旧的,但对于那些可能感兴趣的人,有一个建议

开发一个只处理内存分配但不实现任何实际内存回收机制的GC。 一旦可用的Java堆耗尽,就执行有序的JVM关闭。

JEP草案:Epsilon GC:任意低开销垃圾(非)收集器

如果我有这个问题,我会得到IBM的Jikes Research虚拟机,因为:

  • 运行时系统是用Java编写的(带有特殊扩展)
  • 整个事情被设计为研究工具,相对容易调整。

你无法永远关闭GC,因为Java程序确实会分配并最终耗尽内存,但是很可能你可以通过告诉JVM在堆之前不开始收集来延迟GC的实验期间变得非常大。 (这个技巧也可能适用于其他JVM,但我不知道在哪里找到旋钮开始旋转。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM