Menu

#13 Use of StringBuffer in HtmlGen can cause OutOfMemoryError

open-fixed
core (8)
5
2012-03-21
2012-01-16
Jey Saba
No

At my company, we have JUnit runs with over 8000 tests per run and dozens of runs per week. I found that eventually, UnitTH will run out of heap space and crash when the StringBuffer used to generate the run pages needs to hold 100s of MBs of HTML markup.

Here is a sample of the stack trace that I normally see:

[java] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
[java] at java.util.Arrays.copyOf(Arrays.java:2882)
[java] at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
[java] at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390)
[java] at java.lang.StringBuffer.append(StringBuffer.java:224)
[java] at unitth.html.junit.HtmlGen.generateSpreadBar(HtmlGen.java:606)
[java] at unitth.html.junit.HtmlPackageGen.generatePackageTestCaseSpreadItem(HtmlPackageGen.java:983)
[java] at unitth.html.junit.HtmlPackageGen.generatePackageTestCaseSpreadItems(HtmlPackageGen.java:923)
[java] at unitth.html.junit.HtmlPackageGen.generatePackageTestCaseSpreadList(HtmlPackageGen.java:904)
[java] at unitth.html.junit.HtmlPackageGen.generatePackageRunPage(HtmlPackageGen.java:95)
[java] at unitth.html.junit.HtmlPackageGen.generatePackageRunPages(HtmlPackageGen.java:62)
[java] at unitth.html.junit.HtmlPackageGen.generateHtmlHistory(HtmlPackageGen.java:52)
[java] at unitth.core.UnitTH.unpackAndGenerate(UnitTH.java:414)
[java] at unitth.core.UnitTH.doTheStuff(UnitTH.java:386)
[java] at unitth.core.UnitTH.<init>(UnitTH.java:316)
[java] at unitth.core.UnitTH.main(UnitTH.java:295)

Proposed Fix:

I fixed bug in our in-house repository of UnitTH (we had extended it to add support for NUnit). My solution was to use a BufferedWriter in the methods that are used to create the different HTML files (e.g., generateMainPage(), generatePackageRunPage(), etc.) and pass the bufferedwriter to the different methods used to generate the markup.

With this approach, writing to the BufferedWriter is efficient like appending to StringBuffer. The difference is that the buffer will be flushed to disk periodically, allowing the application to scale up to very large report sizes like in our case.

I am attaching the patch file with my changes, against revision 193 of the main repository.

Discussion

  • Jey Saba

    Jey Saba - 2012-01-16

    Patch file containing my proposed fix

     
  • Andreas Nyberg

    Andreas Nyberg - 2012-01-17
    • labels: --> core
    • assigned_to: nobody --> andnyb
     
  • Andreas Nyberg

    Andreas Nyberg - 2012-01-17

    Thanks, probably should have expected bugs like this to surface after a while. I'll review the patch and it does not sound all too complext to fix though if I recall correctly StringBuffer has been used in quite a number of places.

    Thanks again,
    Andreas

     
  • Andreas Nyberg

    Andreas Nyberg - 2012-03-21
    • status: open --> open-fixed
     
  • Andreas Nyberg

    Andreas Nyberg - 2012-03-21

    Part of 2.0 release. Build snapshot if needed.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.