C
Corey Yeatman
Hi,
I've hit a problem with ant throwing an OutOfMemoryError. I'll
describe what I'm doing and what I think is happening, and if anyone
can confirm this (or suggest an alternative) then that would be great.
What I'm doing is using an ant build file to run a large set of junit
tests automatically and capture the results. It compiles up my java
code-base, then scans the path looking for unit tests to run, and runs
them in groups (depending on the type of unit test and it's
requirements). I have written some custom ant-tasks to find and run
the tests, and these actually call other ant targets in the buildfile
to set up stuff and strip it down again (e.g., rebuild databases,
etc.) required by the tests as necessary. There are about 160 tests
to run.
I've found that after about 90-100 tests, it crashes with an
OutOfMemoryError. Some of the tests are complicated, but they
shouldn't require a massive amount of heap space. I've got the <junit>
target set with fork="yes", so it uses a different JVM to run the
actual tests, so something is sucking up the heap space allocated to
ant's JVM.
I did a bit of reading on the web, and someone mentioned that every
time ant calls another <ant> or <antcall> target and you haven't got
the inheritAll flag set to "false", it duplicates the entire
environment from the parent project, including taskdefs, references,
etc. and passes it to the new task. It also uses a new instance of
it's own internal ClassLoader to pull in taskdef classes, so these can
get loaded over and over again.
My custom task which runs a set of junit tests actually 'loops' within
the task code itself to run all of the tests in the group - and this
runs other ant tasks to do the work. Because it's looping this may
mean a garbage-collect will not free up the memory associated with all
of the sub-tasks until the unit-test-running task finishes, as it may
be hanging on to a reference somewhere.
Anyway ...
I've altered my build files to only pull in taskdef classes
immediately before it needs them, and have used the inheritAll="false"
flag on <ant> and <antcall> statements to stop it pulling in the
entire environment (i.e., I'm passing params into the targets). This
seems to have helped immensely, and now the entire run works again -
BUT, it's still slowly chewing up some of the heap space allocated to
ant's JVM, so I'm not convinced I've fixed it yet (e.g., over the
space of 20 tests, it's gone from using about 10Mb of heap space to
54Mb). I'm really looking to nail this problem so that it doesn't
come back to haunt me in a few months.
Is anyone aware of this type of problem and/or what the correct
approach is to fixing it?
And before anyone suggests it - I've already pushed the heap size up
for ant's JVM using the -Xms and -Xmx flags to 768Mb (!!), but this
isn't helping. Pushing it even higher will just disguise the problem
and not actually solve it so I'm trying to figure out what's going on.
Thanks in advance for any help anyone can give me.
Regards,
Corey.
I've hit a problem with ant throwing an OutOfMemoryError. I'll
describe what I'm doing and what I think is happening, and if anyone
can confirm this (or suggest an alternative) then that would be great.
What I'm doing is using an ant build file to run a large set of junit
tests automatically and capture the results. It compiles up my java
code-base, then scans the path looking for unit tests to run, and runs
them in groups (depending on the type of unit test and it's
requirements). I have written some custom ant-tasks to find and run
the tests, and these actually call other ant targets in the buildfile
to set up stuff and strip it down again (e.g., rebuild databases,
etc.) required by the tests as necessary. There are about 160 tests
to run.
I've found that after about 90-100 tests, it crashes with an
OutOfMemoryError. Some of the tests are complicated, but they
shouldn't require a massive amount of heap space. I've got the <junit>
target set with fork="yes", so it uses a different JVM to run the
actual tests, so something is sucking up the heap space allocated to
ant's JVM.
I did a bit of reading on the web, and someone mentioned that every
time ant calls another <ant> or <antcall> target and you haven't got
the inheritAll flag set to "false", it duplicates the entire
environment from the parent project, including taskdefs, references,
etc. and passes it to the new task. It also uses a new instance of
it's own internal ClassLoader to pull in taskdef classes, so these can
get loaded over and over again.
My custom task which runs a set of junit tests actually 'loops' within
the task code itself to run all of the tests in the group - and this
runs other ant tasks to do the work. Because it's looping this may
mean a garbage-collect will not free up the memory associated with all
of the sub-tasks until the unit-test-running task finishes, as it may
be hanging on to a reference somewhere.
Anyway ...
I've altered my build files to only pull in taskdef classes
immediately before it needs them, and have used the inheritAll="false"
flag on <ant> and <antcall> statements to stop it pulling in the
entire environment (i.e., I'm passing params into the targets). This
seems to have helped immensely, and now the entire run works again -
BUT, it's still slowly chewing up some of the heap space allocated to
ant's JVM, so I'm not convinced I've fixed it yet (e.g., over the
space of 20 tests, it's gone from using about 10Mb of heap space to
54Mb). I'm really looking to nail this problem so that it doesn't
come back to haunt me in a few months.
Is anyone aware of this type of problem and/or what the correct
approach is to fixing it?
And before anyone suggests it - I've already pushed the heap size up
for ant's JVM using the -Xms and -Xmx flags to 768Mb (!!), but this
isn't helping. Pushing it even higher will just disguise the problem
and not actually solve it so I'm trying to figure out what's going on.
Thanks in advance for any help anyone can give me.
Regards,
Corey.