Solved

java.lang.OutOfMemoryError

Posted on 2003-12-08
11
1,419 Views
Last Modified: 2007-12-19
I'm running a Java/J2EE/BC4J/JSP application on a sun box with Oracle 9i and 9iAS and getting a java.lang.OutOfMemoryError when accessing a large recordset a couple of times.  I read on Oracle and Sun websites that this error could be related to the Heap Size setting.  How can I find out what the current setting is and then change it?  What should they be set at?

Parameters: -Xms and -Xmx

Thanks,
Issac Rosa
0
Comment
Question by:irosa
11 Comments
 
LVL 24

Accepted Solution

by:
shivsa earned 500 total points
Comment Utility
To override Sun's JVM default memory setting use for example:

java -ms64m -mx96m ....

From the JDK documentation:
     -ms<number>       set the initial Java heap size
     -mx<number>       set the maximum Java heap size
0
 
LVL 24

Expert Comment

by:shivsa
Comment Utility
you can do is print the mem usage in some places using
RunTime rt = RunTime.getRunTime();
re.totalMemory();
rt.freeMemory();

-ms64m -mx96m
meaning min 64 MB and max 96 MB
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
> and getting a java.lang.OutOfMemoryError when accessing a large
>recordset a couple of times.  

  Can you post some code? You might have some flaws in your code that you will be able to avoid them? If not try shivsa's suggestion.
0
 

Author Comment

by:irosa
Comment Utility
Here is the code for the JSP page.

<%@ page language="java" %>
<%@ page errorPage="/WEB-INF/jsp/Error.jsp" %>
<%@ taglib uri="/WEB-INF/lib/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/lib/DataTags.tld" prefix="bc4j" %>



<!-- Security -->

<% //we explicitely set userCanWrite to true since user permissions will
   //be checked when we display the legal transition statuses
   // changed from SPROCE to SPROCB (Process Batches)
  String THIS_PAGE_FUNCTION_CODE = "SPROCB";
%>
<% boolean userCanWrite = true; //false; %>
<%@ include file="CheckPermissions.txt" %>
<% userCanWrite = true; %>
<!-- /Security -->

<bc4j:ApplicationModule id="appBatchStatusTransition" configname="com.aws.marrs.businessTier.marrsProcessing.statusTransition.StatusTransition_AppModule.StatusTransition_AppModuleLocal" releasemode="Stateful"/>
<bc4j:DataSource id="rowSetLegalStatusTransition" appid="appBatchStatusTransition" viewobject="LegalStatusTransitionsView"/>

<bc4j:ApplicationModule id="appModBatchProcessing" configname="com.aws.marrs.businessTier.marrsProcessing.batchProcessing.BatchProcessing_AppModule.BatchProcessing_AppModuleLocal" releasemode="Stateful"/>
<bc4j:DataSource id="rowSetBatches" appid="appModBatchProcessing" viewobject="BatchProcessingView"/>

<%
  //Set the filter Criteria
  rowSetBatches.getRowSet().setWhereClauseParams((String[]) request.getSession().getAttribute("FilterCriteriaArray"));
  rowSetBatches.getRowSet().executeQuery();
%>

<html>
<head>
      <title>Post Batches</title>
      <SCRIPT language="Javascript1.2" src="<html:rewrite forward='MenuScript'/>"></SCRIPT>
      <LINK href="<html:rewrite forward='IntranetStyle'/>" rel=stylesheet type=text/css>            
</head>

<body LEFTMARGIN=0 TOPMARGIN=0>
<form action="PostBatchView.do" method="post" name="frmPostBatch" id="frmPostBatch" target="_parent">

<table width="720" border="0" cellspacing="2" cellpadding="0" align="left" valign="top" bgcolor="#BEBEBE">
<!-- ** batch start ** -->
 <%
    int batchCount = 1;
    String curBatchId = "-1";
    String newBatchId = "0";
    boolean boolNewBatch = false;
    int rowCount = 0;
 %>
 <bc4j:RowsetIterate datasource="rowSetBatches">
 
    <%
       newBatchId = rowSetBatches.getRowSet().getCurrentRow().getAttribute("BatchInstanceId").toString();
       boolNewBatch = !curBatchId.equals(newBatchId);
       if (boolNewBatch) {
    %>  
        <% if (!curBatchId.equals("-1")) { %>
                </table>
              </div>
            </td>                  
            </tr>      
        <% } %>
         
    <tr class="colhead2">
      <td width="400" class="tiny" align="left" onClick="changeMenu('tree.tables.batch<%= batchCount %>');" style="cursor:hand"><img src="images/mnuPlus.gif" alt="Click to View Cycles In Batch" name="tree.tables.batch<%= batchCount %>.image" id="mnuBatch<%= batchCount %>" border="0">&nbsp;<bc4j:ShowValue datasource="rowSetBatches" dataitem="BatchName"/></td>
      <td width="120" class="tiny" align="left"><strong><bc4j:ShowValue datasource="rowSetBatches" dataitem="StatusCodeDesc"/></strong></td>      
      <td width="200" class="tiny" align="left">
        <input type="hidden" name="BatchId" value="<bc4j:ShowValue datasource="rowSetBatches" dataitem="BatchInstanceId"/>">
        <input type="hidden" name="BatchName" value="<bc4j:ShowValue datasource="rowSetBatches" dataitem="BatchName"/>">        
           <%
              boolean showThisChoice = true;
              boolean userCanSee = true;
              int secureLegalTransitions = 0;
              //SysUserSecurityUtil securityUtil = new SysUserSecurityUtil();
           %>  

           <select name="LegalTransitionStatusCode" size="1" class="tiny">                
            <%
                  String myMasterStatusCode = (String) rowSetBatches.getRowSet().getCurrentRow().getAttribute("CycleFileStatusCode");
                  //set filter criteria for detail
                  rowSetLegalStatusTransition.getRowSet().setWhereClauseParam(0,myMasterStatusCode);
                  rowSetLegalStatusTransition.getRowSet().executeQuery();
            %>          
            <bc4j:RowsetIterate datasource="rowSetLegalStatusTransition">
               <%
                  String legalStatus = (String) rowSetLegalStatusTransition.getRowSet().getCurrentRow().getAttribute("ShortDescriptionLegalCode");
                  String legalStatusTransitionCode = (String) rowSetLegalStatusTransition.getRowSet().getCurrentRow().getAttribute("LegalTransitionStatusCode");

                  //if the user wants to reimport or reprocess, they'll have to use
                  //the cycle status processing screen. This allows them to change
                  //the status by file.
                  if (!(legalStatus == null || legalStatus.equals(""))) {                      
                     userCanSee = securityUtil.userShouldSeeStatus(request.getSession().getAttribute("userId").toString(), legalStatusTransitionCode);                  
                     
                     if (userCanSee) {
                      secureLegalTransitions++;
                %>
                      <option value="<bc4j:ShowValue dataitem="LegalTransitionStatusCode"/>"><bc4j:ShowValue dataitem="ShortDescriptionLegalCode"/></option>
               <% }//end of check for userCanSee
                };//end check for null or ""
               %>
            </bc4j:RowsetIterate>
           
                 <!-- Handle Empty Combo Box Contents (due to Security) -->
                 <option value="-1" selected >
                      <%= (secureLegalTransitions != 0? "" : "Access Denied")  %>
                 </option>
            </select>
      </td>
    </tr>
    <!-- ** cycles in batch ** -->      
        <tr><td colspan=2>
          <div id="tree.tables.batch<%= batchCount %>b" style="display:none"></div>
          <div id="tree.tables.batch<%= batchCount %>">
            <table width="100%" border=0 cellspacing=0 cellpadding=0><script language="JavaScript">initMenu('tree.tables.batch<%= batchCount %>');</script>                  
    <%
       rowCount = 0;
      }
    %>

               <tr class="tiny"><td width="10">&nbsp;</td><td align=left class="row<%=(rowCount % 2 + 1) %>" width="390"><img src="images/spacer.gif" width="16" height="1">&nbsp;&middot;&nbsp;<bc4j:ShowValue datasource="rowSetBatches" dataitem="ModuleCode"/>:&nbsp;<bc4j:ShowValue datasource="rowSetBatches" dataitem="CycleFileName"/>:&nbsp;<bc4j:ShowValue datasource="rowSetBatches" dataitem="CycleCode"/></td><td align="left" class="tiny"><bc4j:ShowValue datasource="rowSetBatches" dataitem="StatusCodeDesc"/></td></tr>      
    <%
        ++rowCount;
     
       if (boolNewBatch) {
          ++batchCount;
          curBatchId = newBatchId;
      }
    %>
  </bc4j:RowsetIterate>        
<!-- ** batch end ** -->      

            </table>
          </div>
        </td>                  
        </tr>            
</table>      
</form>
<% request.getSession().removeAttribute("FilterCriteriaArray");%>
</body>
</html>

<bc4j:ReleasePageResources appid="appBatchStatusTransition" />
<bc4j:ReleasePageResources appid="appModBatchProcessing" />

Here is the code for the query in the bc4j component.
SELECT CellSites_EO.CELL_FACE_SECTOR,              CellSites_EO.CELL_SITE_ID,
       CellSites_EO.SIDBID,                    CellSites_EO.CELL_SITE_NAME,
       CellSites_EO.COMPANY_CODE,             CellSites_EO.HOME_COMPANY_PERCENTAGE,
       CellSites_EO.USID,                    CellSites_EO.CELL_FACE_LOCATION,
       CellSites_EO.IS_EXCLUDED,
       CellSites_EO.IS_OVERRIDE,              CellSites_EO.INCURSION_COMPANY_1,
       CellSites_EO.INCURSION_COMPANY_2,        CellSites_EO.INCURSION_COMPANY_3,
       CellSites_EO.INCURSION_COMPANY_1_PERCENT,CellSites_EO.INCURSION_COMPANY_2_PERCENT,
       CellSites_EO.INCURSION_COMPANY_3_PERCENT,CellSites_EO.COMMENTS,
       CellSites_EO.SWITCH_ID,      
       CellSites_EO.SERVING_PLACE,              CellSites_EO.DATA_SOURCE_FLAG,
       CellSites_EO.IS_LOCKED,                    CellSites_EO.LOCKED_BY_USER,
       CellSites_EO.LOCK_TIMESTAMP,              CellSites_EO.LAST_MODIFIED_USER_ID,
 first_company_sidbids.COMPANY_CODE default_home_company_code,      tb_city_cluster.city_csa_id,
       tb_city_cluster.cluster_csa_id
       
FROM CELL_SITES CellSites_EO,
       (select sidbid, MIN(company_code) company_code
        from company_sidbids
        group by sidbid) first_company_sidbids,              
       (select distinct company_sidbids.company_code, tb_csa_city.csa_id city_csa_id, tb_csa_market.parent_csa_id cluster_csa_id
       from company_sidbids, communication_service_areas tb_csa_city, communication_service_areas tb_csa_market
       where company_sidbids.company_code = tb_csa_city.company_code (+)
           and tb_csa_city.csa_type_name (+) = 'CITY'
       and tb_csa_city.parent_csa_id = tb_csa_market.csa_id (+)
       and tb_csa_market.csa_type_name (+) = 'MARKET') tb_city_cluster

WHERE CellSites_EO.sidbid = first_company_sidbids.sidbid (+)
  AND CellSites_EO.company_code = tb_city_cluster.company_code (+)
  AND (CellSites_EO.CELL_FACE_SECTOR like :0 or '-1' = :1)
  AND (CellSites_EO.CELL_SITE_ID like :2 or '-1' = :3)
  AND (CellSites_EO.SIDBID like :4 or '-1' = :5)
  AND (CellSites_EO.CELL_SITE_NAME like :6 or '-1' = :7)
  AND (CellSites_EO.COMPANY_CODE like :8 or '-1' = :9)
  AND (CellSites_EO.HOME_COMPANY_PERCENTAGE like :10 or '-1' = :11)
  AND (CellSites_EO.USID like :12 or '-1' = :13)
  AND (CellSites_EO.CELL_FACE_LOCATION like :14 or '-1' = :15)
  AND (CellSites_EO.IS_EXCLUDED like :16 or '-1' = :17)
  AND (CellSites_EO.IS_OVERRIDE like :18 or '-1' = :19)
  AND (CellSites_EO.INCURSION_COMPANY_1 like :20 or '-1' = :21)
  AND (CellSites_EO.INCURSION_COMPANY_2 like :22 or '-1' = :23)
  AND (CellSites_EO.INCURSION_COMPANY_3 like :24 or '-1' = :25)
  AND (CellSites_EO.INCURSION_COMPANY_1_PERCENT like :26 or '-1' = :27)
  AND (CellSites_EO.INCURSION_COMPANY_2_PERCENT like :28 or '-1' = :29)
  AND (CellSites_EO.INCURSION_COMPANY_3_PERCENT like :30 or '-1' = :31)
  AND (CellSites_EO.SWITCH_ID like :32 or '-1' = :33)
  AND (CellSites_EO.DATA_SOURCE_FLAG like :34 or '-1' = :35)
  AND (tb_city_cluster.cluster_csa_id like :36 or '-1' = :37)
  AND (tb_city_cluster.city_csa_id like :38 or '-1' = :39)
  AND (CellSites_EO.COMMENTS like :40 or '-1' = :41)

order by CellSites_EO.SIDBID, CellSites_EO.SWITCH_ID, CellSites_EO.CELL_SITE_ID, CellSites_EO.CELL_FACE_SECTOR
0
 
LVL 24

Expert Comment

by:shivsa
Comment Utility
could u just try to run this with more heap sizes as i suggested and see if it works.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 1

Expert Comment

by:gagaliya
Comment Utility
Try using resultset instead of rowset. just make sure you close the connection after you done with it.
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
what servlet container is 9ais using?
0
 
LVL 1

Expert Comment

by:matt_law
Comment Utility

remember that mx shouldn't be larger than your physical memory, and that setting them differently will allow the heap to shrink as well as grow, ie -ms64 -mx128 means the heap will grow to 128 under heavy usage but then the VM will garbage collect until the heap is back to 64, if it can. This can cause performance degradation if your app does a lot of work (lots of users, many threads etc) and you set the limits wide apart. Lots of objects will go through the create, use, discard cycle and the VM will spend more and more time garbage collecting and less time doing useful work.

In short, up the sizes, and set them both the same (then the VM won't want to start shrinking the heap). Make sure you close connections, dereference objects to allow them to be garbage collected and also try System.gc() to clean up before you do something you think is memory heavy. Bear in mind System.gc() is only a suggestion to the VM to garbage collect.

Here's something about perf. tuning bc4j, might give you some other pointers ...

http://radio.weblogs.com/0118231/stories/2003/03/26/viewObjectTuningTipsForBestPerformance.html
0
 

Expert Comment

by:javaTL
Comment Utility
If the DATA is large enough, it will sooner or later throw an OutOfMemoryError, no matter how large the heap size.
As an alternative, try to load the data from the server in PAGES which are loaded according to the users current view.
Though this might slow the response time, it should solve the OutOfMemoryError.
0
 
LVL 35

Expert Comment

by:girionis
Comment Utility
 I agree with javaTL, if the data is large enough you will eventually run out of memory. A few things:

a) Try to access the recordset only once and keep it in memory for further processing. Do not access it several times exept if the data changes all the time. If you do need to acees it several times make sure you set the previous variables to null.

b) as javaTL suggested it might be betetr to bring the results back in groups of (lets say) 100 and display them in separate pages to the user.
0
 
LVL 3

Expert Comment

by:mjzalewski
Comment Utility
I think your 'Out of Memory' might not be caused by a large resultset, unless you are working with an extremely large result set (more than 10K rows)  or an extremely small heap size (less than the default of 128M). Also, the part where you said 'large recordset a couple of times' leads me to guess that the large recordset works OK the first time, maybe even the second time. But if you keep requesting large recordsets, eventually you get the 'Out of Memory'

If this is the case, I would look for a resource that is not being returned to the system.

Here is a 'back of the envelope' calculation.

You are selecting about 25 columns, many of which are simple numbers. So lets say each column takes an average of about 100 bytes.

That means each row takes 2.5k. Let's say that the wrapper objects need another 2.5k, giving 5k per row.

So if this is true, 200 rows would require 1 M of heap spece. (It might be as many as 2000, because I am trying to make a pessimistic estimate. Also, for the columns that have String values, identical columns will eventually share memory)

Now the JSP and Servlet container will need some heap space to operate. Let's say it needs 10 - 20 MB, + maybe another 5 - 10 MB per concurrent request. I believe the default heap size is usually 128 MB, so that leaves about maybe 100 MB for the query data.

This means that your page should be able to accomadate about as many as 1/4 million rows, but certainly at least 10,000 rows (if only a single user uses your system. If more than one request is being processed at a time, you can split the 1/4 million among all concurrent requests).

And... if your query can return 10,000 rows, and you want to display all that on a single web page... It's like JavaTL suggested. You might want to add paging to your design.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now