cancel
Showing results for 
Search instead for 
Did you mean: 

Possible of memory leak in the loop

Former Member
0 Kudos

Recently my application do get OutOfMemory issue. I realized the memory is keep on stack up as i saw in the task manager, the jlaunch keep growing and it won't drop back. That day i'm running a search function and it will query the table to retrieve the data. The jlaunch shoot from 500MB -> 2.2GB and now remain in there. Wondering is it during it query it populate at least 10,000 records into the arraylist and then the memory already allocated and once i finish run the function, it will clear the allocated memory to re-use it.


public ArrayList ejbHomeInJDBCConnection(Map map){
	ArrayList beanList = new ArrayList();
	try{
		Context ctx = new InitialContext();
		DataSource ds = (DataSource) ctx.lookup("jdbc/POOL");
		Connection con = ds.getConnection();
		String query = "SELECT * FROM USER WHERE ";
		for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
			Object key = iterator.next();
			if(key.toString().startsWith("TIME") | key.toString().startsWith("TIMEIN")){
				long longValue = Long.parseLong(map.get(key).toString());
				query += key.toString()+ longValue + " AND "; 	
			}else{
				String value = (String)map.get(key);
				query += key.toString()+ value + " AND "; 	
			}
		}
		String newquery = query.substring(0, query.length()-5);
		newquery += " ORDER BY TIMEIN DESC";
		Statement stmt = con.createStatement();
		try {
			ResultSet rs = stmt.executeQuery(newquery);
		    try {
				while (rs.next()){
					InBean bean = new InBean();
					bean.setSmsId(rs.getString("EMP"));
					.......
					beanList.add(bean);
				}
			}finally{
				rs.close();
			}
		}finally{
			stmt.close();
	}catch(Exception e){
		System.err.println(e.fillInStackTrace());
    }
return beanList;

Wondering is it the InBean will cause any memory leak as if there is 10,000 records, which mean it will create 10,000 objects and once it add into the arraylist the previous bean is not in use, will the GC clear it as i didn't set it as null. Do i need to do something like reallocate/defragment the memory?

Thanks.

Accepted Solutions (1)

Accepted Solutions (1)

ravindra_bollapalli2
Active Contributor
0 Kudos

hi chan,

might be the memorry issue,

if we storing the single interger value, problem may not occur, if we store the object(with some data members)-- my level of understiandig-- coz i do't know the what is the bean returing (IBEAN)

http://help.sap.com/saphelp_nw70/helpdata/EN/a2/852aca5cd96f4796e51ba0f7a28926/frameset.htm

might be we have to clear the meomroy or restart the jlaunch instance every time

let me know much i understand u r problem

ravindra

Former Member
0 Kudos

Hi ravindra,

Thanks for your help.

I understand that it will create a new object in the loop if there is more than 1 recordset due to the InBean bean = new InBean(); is in the loop. What if this put at the top, will it only create 1 bean object?

The bean is my table data. So it will store all the data and then add in the arrayList and pass back to the function to display.

As like what you said, is it possible i clear up the memory in program code instead of restart the instance in order the jlaunch back to normal.

regards,

adrian

Former Member
0 Kudos

Hi,

Can you try a LinkedList implementation instead of ArrayList? - You can use the List interface as the method return. If this doesn't help you, try using either the ArrayList constructor with the capacity (I think you can perform a count before starting the List) - or use the method ensureCapacity.

This will save a lot of memory while creating the List.

Rgds,

Daniel

Former Member
0 Kudos

I had check out LinkedList, but i think ArrayList is better for my case. I think i will remain using ArrayList but will a capacity for my arrayList when i create it. But another concern is when i do a count, it will consume of memory and performance as it need to query the database. I need to use less memory but this seem like using more.

Your meaning of saving a lot of memory creating a list is reffering to ArrayList with a capacity?

Actually my concern is in my function i have a arrayList, as example i have 10k records then it will be an arrayList[ 10000 ]. It will need a memory space to create it rite. Once i return the arrayList to the calling function, will GC clear my arrayList[ 10000 ] memory space? Or it will remain at there and i cannot clear it? So it the end it will used up my java memory. Eventhough if i can perform a cleanup, but how can i identify the arrayList that i created previously.

Thanks.

Former Member
0 Kudos

Hi,

I'm sure a "count" would not generate the overhead you are concerned.

To understand some aspects, you need to read the source files of Java, and understand how the stack would work in your case.

Evertime you "add" an element to you list, the implementation will run the ensureCapacity, and grown the list one by one. Understand that the list is an Array with a lot more functions, but below, you are still working with an Array, and it needs to have a defined size. Everytime you add, it's doing a System.arraycopy(all the crap) - So you can save this, everytime you add something if you create your List with the right size.

Note, this is not an issue if we consider small lists, of small objects, but working with large lists, you can feel slow downs.

About the GC stuff, well.. I'm sure you can do some reading how it works. One good start point would be

Link: [http://java.sun.com/docs/hotspot/gc1.4.2/]

I'm sure you don't need that, but still, it's good reading. Maybe you should just increase your heap size, or you can manually clear the List using list.clear();

Rgds,

Daniel

Answers (1)

Answers (1)

siarhei_pisarenka3
Active Contributor
0 Kudos

Hi Adrian

1. I do not see Connection.close() method in your code. I'm not sure if it's strongly necessary, but try to close connection after use. It'll release JDBC resources.

2. I think the following code is not efficient if you are making the same SQL many times:

Statement stmt = con.createStatement();

Official Javadoc says the following about the method:

>If the same SQL statement is executed many times, it may be more efficient to use a PreparedStatement object.

I suggest you to try

PreparedStatement Connection.prepareStatement(String sql);

...instead.

> A SQL statement with or without IN parameters can be pre-compiled and stored in a <code>PreparedStatement</code> object. This object can then be used to efficiently execute this statement multiple times.

BR, Siarhei