0

I am trying to display 5000 records on page using JSP. But I am getting out of memory exception. I am doing it as,

<TABLE><tr><td>Header1</td><td>Header2</td><td>Header3</td><td>Header4</td><td>Header5</td></tr>");
    <%Test test = new Test();
         List myList = test.fetchdata();

        Iterator itr  = myList.iterator();
        while(itr.hasNext())
        {       
          Object[] row = (Object[]) itr.next();
          String hdr1 = (String) row[0];
          String hdr2 = (String) row[1];
          String hdr3 = (String) row[2];
          String hdr4 = (String) row[3];
          String hdr5 = (String) row[4];
              stringBuilder.append"<tr><td>'"+hdr1+"'</td><td>'"+hdr2+"'</td><td>'"+hdr3+"'</td><td>'"+hdr4+"'</td><td>'"+hdr5+"'</td></tr>");              
        }
 stringBuilder.append("</TABLE></body></html>");
 out.print(stringBuilder.toString()); 
  %>

1) if I want to decide to keep 5000 records on screen , is there anything wrong in my code

2) Or will this error will go if I use pagination etc ?

  • 7
    "I am trying to display 5000 records on page" - no, you don't want to do that. More importantly, your users don't want to digest that many records. You're likely to eliminate the error with pagination. If it's good enough for Google and Stackoverflow, why not for you? – duffymo Oct 02 '12 at 01:42
  • 2
    There's no decent website that show more than 100 rows per page. You should paginate your datatable in order to improve the performance. Also, **you should not use** scriptlets in your code, read (and apply) [How to avoid Java Code in JSP-Files?](http://stackoverflow.com/a/3180202/1065197). – Luiggi Mendoza Oct 02 '12 at 01:46
  • 1
    Strings take up memory and you are creating thousands of them here, which could fill memory up quickly. Instead of making 5 strings each time (hdr1-5) I would just put them directly in the stringbuilder.append. Also, use multiple ".append()" in your builder like stringBuilder.append("").append(row[0]).append() etc.. – Logan Oct 02 '12 at 03:00
  • Hello @Logan. can you please let me know how I can achive in my Code whatever you saying ..." I would just put them directly in the stringbuilder.append. Also, use multiple ".append()" in your builder like stringBuilder.append("").append(row[0]).append() etc.. " – user1713275 Oct 02 '12 at 04:07
  • I think he wants you to use `...'"+ ((String) row[0]) + "'...` instead of assigning a new String in every iteration and using its reference in the append. You should also do this if you decide to use pagination, which is what I also recommend using. – devrys Oct 02 '12 at 06:47

2 Answers2

1

Because your code example is somehow broken it is hard to say, but there are two places that cause the memory problem. A) your test.fetchdata() B) your append to the StringBuilder

Starting with B, if you are directly on the JSP you could try outputting it directly, rather than to use the StringBuilder. Depending on the JSP compiler it might produce smaller StringBuilders that should not take up much memory.

But most likely the Problem is in A. You get back a long list which already occupies a lot memory. You can only optimize by doing some lazy loading of results (in the iterator) or as you proposed yourself by pagination (which is recommendable, as all the comments indicate :-) )

And there is one last option maybe worth trying when there are lots of duplicate strings. inside the fetchdata() method use .intern() before you store the String in the array. This prevents multiple identical strings to take up additional heap at the cost of a bit cpu time for calculating this.

Fabian Lange
  • 1,786
  • 1
  • 14
  • 18
0

I was thinking something more like this with append.

    List myList = test.fetchdata();

    Iterator itr = myList.iterator();

    StringBuilder stringBuilder = new StringBuilder("");

    while (itr.hasNext()) {
        Object[] row = (Object[]) itr.next();
        String hdr1 = (String) row[0];
        String hdr2 = (String) row[1];
        String hdr3 = (String) row[2];
        String hdr4 = (String) row[3];
        String hdr5 = (String) row[4];
        stringBuilder.append("<tr><td>'").append(hdr1)
                .append("'</td><td>'").append(hdr2).append("'</td><td>'")
                .append(hdr3).append("'</td><td>'").append(hdr4)
                .append("'</td><td>'").append(hdr5).append("'</td></tr>");
    }
    stringBuilder.append("</TABLE></body></html>");
    out.print(stringBuilder.toString());

Or possibly refactoring that into this.

    List myList = test.fetchdata();

    Iterator itr = myList.iterator();

    StringBuilder stringBuilder = new StringBuilder("");

    while (itr.hasNext()) {
        Object[] row = (Object[]) itr.next();
        stringBuilder.append("<tr><td>'").append(row[0])
                .append("'</td><td>'").append(row[1]).append("'</td><td>'")
                .append(row[2]).append("'</td><td>'").append(row[3])
                .append("'</td><td>'").append(row[4]).append("'</td></tr>");
    }
    stringBuilder.append("</TABLE></body></html>");
    out.print(stringBuilder.toString());
Logan
  • 2,369
  • 19
  • 20