使用Java泛型可能会挂起编译器

时间:2013-01-02 00:28:24

标签: java generics compilation hang

我有大约55个Java接口和5个抽象类。每个声明使用相同的通用参数集:它列出了大约60个声明,因此每个实现都知道每个其他实现的特定类型,并在方法参数中替换此类型并根据需要返回。似乎这种(可能过度)使用泛型导致编译器挂起。编译器抛出OutOfMemoryError,但似乎没有终止。

考虑到我的情况,甚至包含其中一个声明的代码清单有点困难,但列表的一部分可能是可能的。接口声明通常指定大约五种方法的集合,但在声明中使用泛型会将源模块的大小增加到大约一千行。

我的情况可能是编译器实际进入无限循环的情况,还是我应该给它更多的内存?抛出OutOfMemoryError异常大约需要20分钟,所以我担心如果我只是通过一个因子增加给编译器的内存,那么编译器抛出异常就会花费更长的时间。

我正在使用NetBeans作为我的编辑环境,但是一旦启动NetBeans就一直在运行clean / build脚本。我这样做是因为NetBeans在启动后开始检查我的代码的语法时很快就会变得没有响应。我正在使用Ubuntu 10.4(我想 - 我是从Windows写的)。我已经在Ubuntu环境中打开一个命令行,运行NetBeans作为后台进程,检查输出并使用gedit更正任何源代码错误,查杀并重新启动NetBeans。这似乎就足够了,直到我发现不再产生语法错误。我不知道如何从命令行运行clean / build脚本。

很抱歉,如果这个问题看起来含糊不清,但如果其他人可以帮助我,那么我可能会更具体一点。

感谢任何考虑过的建议。

1 个答案:

答案 0 :(得分:3)

听起来我觉得你对泛型有一些过于复杂的使用,这导致Java编译器使用过多的内存来试图表示泛型类型的扩展。失败之前的很长一段时间可能是由于“垃圾收集死亡螺旋”...... GC花费的时间越来越多,每次回收的记忆越来越少,直到它最终不得不放弃。

如果您无法向我们展示代码,唯一可能的建议是使用更大的堆运行编译器,并查看是否能解决问题。

  

我不知道如何从命令行运行clean / build脚本。

嗯,我想你需要明白这一点。它可以帮助你解决问题,无论如何要知道这些事情是很重要的;例如这样您就可以使用CI系统来构建代码并运行测试。 (并且您可能需要从命令行运行脚本以使构建在具有堆的单独JVM中运行,该堆的大小可以独立于IDE进行控制。)


您对泛型的复杂使用也可能包含Java编译器无法处理的病态(可能是荒谬的)。

  

关于我的通用声明的一个可能的麻烦来源是它们是自我引用的;一个声明指的是另一个引用第一个声明。

是的......那就是我所说的那种事。如果你不小心,你可能会得到一些无意义的东西(从Java的角度来看),它涉及无限类型的扩展。