Java Ant taskdef-PermGen空间不足
使用创建子项目(如Java Ant taskdef-PermGen空间不足,java,ant,typedef,out-of-memory,taskdef,Java,Ant,Typedef,Out Of Memory,Taskdef,使用创建子项目(如和)的Ant任务在重复调用时可能会由于以下错误之一而导致生成失败: java.lang.OutOfMemoryError:PermGen空间 java.lang.OutOfMemoryError:java堆空间 只有在使用或定义了一个被调用的任务时,才会发生此错误,并且在使用与Ant捆绑的任务(如)时不会出现此错误 有没有一种方法可以避免OutOfMemoryError而不增加 最大Java堆大小?虽然增加堆的大小对于 然而,如果添加更多内存密集型任务,问题仍然会再次出现
和
)的Ant任务在重复调用时可能会由于以下错误之一而导致生成失败:
- java.lang.OutOfMemoryError:PermGen空间
- java.lang.OutOfMemoryError:java堆空间
或
定义了一个被调用的任务时,才会发生此错误,并且在使用与Ant捆绑的任务(如
)时不会出现此错误
有没有一种方法可以避免OutOfMemoryError
而不增加
最大Java堆大小?虽然增加堆的大小对于
然而,如果添加更多内存密集型任务,问题仍然会再次出现
下面的示例任务和关联的
build.xml
文件导致
OutOfMemoryError
在我的Linux机器上,Java堆设置为10 MB(对于
测试)。Ant任务构造了一个内存不足的对象(在本例中是Guice)
关闭模板(模块)的注入器,然后重复调用该注入器
使用
CreateGuiceInjectorTask.java
编译文件
使用所描述的方法,我能够解决内存问题,至少对于您发布的简单示例代码是这样
概括地说,问题在于每次通过antcall
Ant使用taskdef时,都会使用不同的类加载器,因此很快就会耗尽permgen。为了确认这一点,您可以修改您的类以打印classloader哈希代码——您将在每次迭代中看到它的不同
解决方法是将taskdef打包为一个名称空间,并使用antlib名称空间加载它。结果是使用了Ant自己的类加载器。为了实现这一点,必须将类放在Ant类路径上
为了测试这一点,我将您的测试类放在一个包名称空间(称为memtest)中,进行编译,然后在包目录中添加一个antlib.xml,如下所示:
<antlib>
<taskdef name="create-injector" classname="memtest.CreateGuiceInjectorTask" />
</antlib>
表示“资源在默认类路径中的要求可能会在未来的Ant版本中被删除。”这取决于如何实现,这项工作可能会在将来中断。那么,您想要一种不用太多内存运行内存密集型任务的方法吗?祝你好运…我想知道蚂蚁一开始的最大堆数是10米?我投票决定结束,因为这不是一个真正的问题。。。如果你的应用程序需要更多的内存,你有两个选择:1)增加内存,2)减少功能。尽管投票和评论非常接近,但这个问题描述了一个清晰、真实的问题,解决方案非常简单,因此似乎与“不是真正的问题”完全相反。
<?xml version="1.0" encoding="UTF-8"?>
<project name="out-of-memory-test" basedir=".">
<property name="build.dir" location="${basedir}/build" />
<property name="CreateGuiceInjectorTask.jar"
location="${build.dir}/CreateGuiceInjectorTask.jar" />
<taskdef name="create-injector"
classname="CreateGuiceInjectorTask"
classpath="${CreateGuiceInjectorTask.jar}" />
<target name="call-create-injector">
<create-injector />
</target>
<target name="test"
description="Create multiple injectors until out of memory">
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
<antcall target="call-create-injector" />
</target>
</project>
$ ant test
test:
call-create-injector:
[create-injector] Constructed Guice injector...
call-create-injector:
[create-injector] Constructed Guice injector...
...
call-create-injector:
BUILD FAILED
Could not create type create-injector due to java.lang.OutOfMemoryError: Java heap space
<antlib>
<taskdef name="create-injector" classname="memtest.CreateGuiceInjectorTask" />
</antlib>
<project name="out-of-memory-test" basedir="." default="test" xmlns:mt="antlib:memtest">
<target name="call-create-injector">
<mt:create-injector />
</target>