JApplet gets a java.lang.OutOfMemoryError exception on ObjectInputStream.readObject(Unknown Source)
I've written a JApplet that that connects to a server. On connecting it receives an ImageIcon. On receipt it send a String "I" to the server开发者_开发问答 to confirm. This signals the server to send the next imageIcon.
while(noExceptions){
try{
Object something = in.readObject();
if(something instanceof ImageIcon){
camDisplay.setIcon( (ImageIcon)something );
validate();
sendMessage("I");
}else{
System.out.println("What the hell was that?!");
}
Runtime rt = Runtime.getRuntime();
rt.gc();
}catch(Exception e){
noExceptions=false;
...
}
}
I added the call to the garbage collector when I first got the exception but it didn't help. I put in some printlns and it always crashes on the 128th image. Exception is thrown at Object something = in.readObject();
camDisplay is a JLabel that is shown in the applet.
Exception in thread "Thread-12" java.lang.OutOfMemoryError: Java heap space
at java.lang.reflect.Array.newArray(Native Method)
at java.lang.reflect.Array.newInstance(Unknown Source)
at java.io.ObjectInputStream.readArray(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at javax.swing.ImageIcon.readObject(Unknown Source)
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at RoboClient.run(RoboClient.java:226)
at java.lang.Thread.run(Unknown Source)
FIX:
System.out.println((sendImageCount++)+" send image");
out.writeUnshared( new ImageIcon(_image) );
out.flush();
if(sendImageCount>100){
out.reset();
sendImageCount=0;
}
See ObjectOutputStream.reset() and ObjectOutputStream.writeUnshared().
One crude way to address this problem is to flush the inputstream after retrieving every x(say 50 in this case) ImageIcons and close the inputStream and reOpen to get the remaining ImageIcons. Now the GC will be able to garbage the earlier retrived imageicons.
Looks like the Inputstream holds the references of the ImageIcons which is preventing from Gced.
精彩评论