Link to home
Start Free TrialLog in
Avatar of tbboyett
tbboyettFlag for United States of America

asked on

java out of memory error

I have a dialog that the user specifies a file that contains information that needs to be stored in the database, then they click update.  This takes the information from the file and does all the necessary checks on the data.  Only the checks have been made, it splits the data into serialized objects that are appropriate for that data.  Then i call methods from the server via RMI and pass these objects to those methods and insert the data appropriately.  This works perfect except it gives an out of memory error occasionally.  From what I see it's not at a given amount of records.   This error has occured anywhere between inserting 750 records to 20,000 records.  Below is the error:

java.rmi.ServerError: Error occurred in server thread; nested exception is:
      java.lang.OutOfMemoryError
      at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:289)
      at sun.rmi.transport.Transport$1.run(Transport.java:148)
      at java.security.AccessController.doPrivileged(Native Method)
      at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
      at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
      at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
      at java.lang.Thread.run(Thread.java:552)
      at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
      at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
      at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
      at Server.DataServer_Stub.saveCarMileage(DataServer_Stub.java:857)
      at ClientGUI.UpdateCustomersDlg.run(UpdateCustomersDlg.java:783)
      at java.lang.Thread.run(Thread.java:613)
Caused by: java.lang.OutOfMemoryError

Does java store the serialized objects in memory until the process is complete or do you think this is occuring for some other reason?  Thanks for any help.  
Avatar of tbboyett
tbboyett
Flag of United States of America image

ASKER

Any ideas would be helpful
ASKER CERTIFIED SOLUTION
Avatar of hoomanv
hoomanv
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks hoomanv, how do you determine the current heap size?

Also, is this strickly commandline commands and what is a recommended max heap size?
> Thanks hoomanv, how do you determine the current heap size?
Runtime.getRunTime().maxMemory()

or
import java.lang.management;
MemoryUsage mu = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
now use these methods on mu

 long getInit()
          Returns the amount of memory in bytes that the Java virtual machine initially requests from the operating system for memory management.
 long getMax()
          Returns the maximum amount of memory in bytes that can be used for memory management.
 long getUsed()
          Returns the amount of used memory in bytes.
Is it possible to set the heap size to automatically change as it needs to ?
I think there is no way to change the JVM heap size during runtime.
Is it possible that it's the database running out of memory rather than java or will the error be thrown only if the memory issue is with java?

I will try this out and get back to you shortly.  Thanks again.
> Is it possible that it's the database running out of memory rather than java or will the error be thrown only if the memory
> issue is with java?

this error will be thrown only when jvm runs out of memory. the database's (i.e mysql) memory is separate from JVM memory
have a look here
http://www.onjava.com/pub/a/onjava/2001/08/22/optimization.html

and
http://publib.boulder.ibm.com/infocenter/wasinfo/v4r0/index.jsp?topic=/com.ibm.websphere.v35.doc/wass_content/0901.html
at section "Heap Size Settings"
One more question, would I need to change the heap size on both the server and client machines or just server? or is that undeterminable?
> would I need to change the heap size on both the server and client machines or just server?
you have to do it where ever you need more heap size, depending on what (memory consuming operations) they are intended to do
>> This error has occured anywhere between inserting 750 records

750 is a small number. What is the record-size? If the error is thrown even with those many records, there might be problems in the code (make sure you use StringBuffers or StringBuilders, make sure you close all streams and connections once you are done with them, that too in finally blocks, etc)
>  java -Xms<initial heap size> -Xmx<maximum heap size>  

When I use this command, it just prints out the options, do i need to change or add something to the command?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> there might be problems in the code

I'm going to look back over all the code to make sure of this. thanks
>> java -Xms<initial heap size> -Xmx<maximum heap size>

And I hope you added the class-name after that :)

java -Xms20m -Xmx80m packagename.MainClassName
> And I hope you added the class-name after that :)
silly mistake on my part.  I did not add the class-name

I was trying to check to see if it was running out of memory.  What i did was created a simple app using what hoomanv posted above:

import java.lang.management.*;
public class MemoryTest {
  public static void main( String[] args)  {
    try {
      MemoryUsage mu = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
      long init = mu.getInit();
      long max = mu.getMax();
      long used = mu.getUsed();
     
      System.out.println("Initial memory: " + init + "\n Max memory: " + max + "\n Used memory: " + used);
    }catch(Exception e) {
      System.out.println(e);
    }
  }
}

I am running the long process that inserts the records, and occasionally running this small app to see if there were any changes in the memory being used.  Every single time i get the same results as if it's not using any extra memory:

Initial memory: 0
Max memory: 66387968
Used memory: 395864

Am I approaching this wrong?  I just wanted  to make sure before actually changing the heap size.
Thanks again
>> occasionally running this small app

This App will run in a separate VM instance if you run it as a separate main (). The right way to check your app's memory usage is through a profiler:

http://www.ej-technologies.com/products/jprofiler/overview.html 

http://java-source.net/open-source/profilers 

http://www.manageability.org/blog/stuff/open-source-profilers-for-java