2010-06-05 75 views
15

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

+4

无渣垃圾收集,就像,以及C/C++! – 2010-06-05 10:48:48

+1

根据http://forums.java.net/jive/thread.jspa?messageID=208939&tstart=0在早期版本的Java中可以禁用gc,但不再可能。 – 2010-06-05 10:50:11

+8

@米奇小麦,没有。它远离C++ **,没有缓冲区溢出,很少或没有未定义的行为。 – 2010-06-05 14:05:45

回答

15

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

执行此操作的简单方法是运行带有一个非常大的GC以便GC无需运行的堆栈的JVM。设置-Xmx-Xms选择一个较大的值,然后打开GC日志记录,以确认GC没有为您的测试期间运行。

这比修改JVM更快更直接。


(事后看来,这可能无法正常工作。我依稀记得看到有证据表明暗示JVM不总是尊重-Xms设置,尤其是如果这是真的大了。不过,这种做法是值得在尝试一些更加困难的方法之前尝试...像修改JVM一样)。

此外,整个事情让我感到不必要的(即使是反效果的),你实际上试图达到的目标。 GC不会丢弃物体,除非它们是垃圾。如果它们是垃圾,你将无法使用它们。 GC禁用/取消的系统的性能不会指示应用程序将如何执行。

4

Sun的JVM没有这样的选项。 AFAIK,其他的JVM都没有这个选项。

你没有说明你正准备实现的是什么,但是你有两个选择之一:或者使用一个探查器,看看GC正在做什么,这样你就可以考虑到它的影响。另一个是从源代码中编译一个JVM,并从那里禁用GC。

+1

感谢您的回答。我基本上是分析Java程序。我想找到一种快速的方法来将所有对象保存在内存中,以进行简单的初始概念验证。 – 2010-06-05 11:49:08

8

根据您的需求,这或许可以工作:

使用您可以指定自己的实现API类的-Xbootclasspath选项。然后你可以重写Object的实现,并将其添加到构造函数globalList.add(this)中以防止对象被垃圾收集。这确实是一种破解,但对于简单的案例研究来说,这可能就足够了。

另一种选择是采用开源jvm并注释启动垃圾回收的部分。我猜想这并不复杂。

+1

重写对象听起来像一个绝妙的主意。但是当我尝试它时,它给了我一个巨大的堆栈跟踪错误。我认为这是有道理的,因为我想在Object的构造函数中执行的任何代码都需要调用Object的构造函数。 – 2010-06-05 11:51:07

+2

好点。一个简单的globalList.add(this)可能会导致无限递归。你将不得不做更多的切肉刀。例如,你可以实现你自己的列表结构,它被排除在列表中。 – aioobe 2010-06-05 12:02:59

+0

这是否会阻止世代收集的“小集合”循环? “在堆栈上新建”是否为 – cody 2016-08-29 16:52:54

1

也许你可以尝试让你的虚拟机的可用内存足以让GC永远不会运行。

我(allbeit有限)的经验使我认为,虚拟机,默认情况下,极其懒惰,极不情愿运行GC。

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

1

你可以得到一个开源的JVM,并禁止GC,例如Sun's Hotspot

如果没有垃圾收集你认为这样的代码的语义是什么?

public myClass { 

     public void aMethod() { 

      String text = new String("xyz"); 

     } 

} 

在没有GC的情况下,任何新的项目和堆栈作用域引用都不能被回收。即使你自己的类可以决定不使用这样的局部变量,或者只使用基本类型,我也不会看到你将如何安全地使用任何标准的Java库。

我很想知道更多关于您的使用场景。

+1

? – aioobe 2010-06-05 11:30:39

+0

如果你打算开发一个开源的JVM,为什么不从Sun的Hotspot开始? – Ken 2010-06-05 15:01:04

+0

@aioobe是的,可以说更好 - 如果你愿意,随意编辑。代码示例我希望能够说明我的意思。在退出方法时,局部变量* text *消失了,我们没有引用新的对象,也没有办法整理。 – djna 2010-06-05 18:54:43

0

如果我有这个问题,我会得到IBM的Jikes Research Virtual Machine因为:

  • 运行时系统是用Java编写本身(特别扩展)
  • 整个事情被设计成一个研究车辆并且相对容易调整。

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

1

看一看Oracle's JRockit JVM。我已经看到这款JVM在英特尔硬件上具有非常好的近似确定性能,并且您可以使用Mission Control实用程序刺激并戳穿运行时,以了解它的表现如何。

尽管无法完全关闭GC,但我相信您可以使用-Xnoclassgc选项来禁用类的集合。可以将GC调整为minimize latency,但会增加内存消耗。如果您要走此路线,您可能需要许可证才能将延迟降至最低。

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

1

只有在GC没有真正需要时才能关闭GC(否则您的应用程序将耗尽内存),并且如果您不需要GC,则无法运行GC。

最简单的选择是不放弃任何对象,这将避免执行GC(并且将最大内存设置得非常高,以免用完)。

您可能会发现启动时启动GC,并且运行时可能会认为运行不可接受。

1

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

+0

您能否提供您所说的方法的源代码[Test Setup]? – Pushparaj 2015-03-13 13:58:54