• Post Reply Bookmark Topic Watch Topic
  • New Topic

out of memory: heap overflow  RSS feed

 
Randall Twede
Ranch Hand
Posts: 4696
8
Java Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i dont have my laptop with me so i will try to explain in english. i have a paint program. it works fine unless the user draws freehand for a long time. then it runs out of memory. calling gc() doesn't help. here is how it goes(simplified).

BufferedImage temp;
mouseDragged() //mostly done in PaintComponent()
{
draw temp if it is not null
draw a line
create image by painting the JPanel to a BufferedImage
assign it to temp
}
mouseReleased()
{
add temp to the ImageStack
}
as you can see many BufferedImages are created just so they can be drawn on the JPanel. only on mouseReleased() does one get saved. the others are all garbage. as far as i can tell they are no longer referenced, but the garbage collector just lets them run the app out of memory. any ideas?
 
Mansukhdeep Thind
Ranch Hand
Posts: 1163
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please use code tags when pasting code:



Becomes legible and clear. Also indent the code.
 
Randall Twede
Ranch Hand
Posts: 4696
8
Java Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
well, like i said i don't have my laptop here so i could not post actual code. that was what you call pseudocode.
 
Randall Twede
Ranch Hand
Posts: 4696
8
Java Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i dislike gc() more and more. it just lets the program crash rather than reclaiming garbage. i know that usually there is a better way to write your code to avoid this, but i have no idea how to do it in this circumstance. in C++ we had to do it ourself(long time ago, can't remember how). can't we do that in java too? there might be a better way to do what i am trying to do, but i don't see it.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Randall Twede wrote:i dislike gc() more and more. it just lets the program crash rather than reclaiming garbage. i know that usually there is a better way to write your code to avoid this, but i have no idea how to do it in this circumstance. in C++ we had to do it ourself(long time ago, can't remember how). can't we do that in java too? there might be a better way to do what i am trying to do, but i don't see it.


The garbage collector will not throw an out-of-memory error, unless it runs a full GC and can't reclaim the memory needed. And this is regardless of whether you call the gc() method or not.

Henry
 
William Brogden
Author and all-around good cowpoke
Rancher
Posts: 13078
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The usual cause is failure to use the Graphics dispose() method to recover resources after drawing.

Bill
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:
The garbage collector will not throw an out-of-memory error, unless it runs a full GC and can't reclaim the memory needed.


It can calso throw one if the JVM is spending more than 95% of its cycles doing GC and reclaims less than 5% of the heap as a result. Or something like that. The numbers are configurable by JVM startup args.
 
Randall Twede
Ranch Hand
Posts: 4696
8
Java Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
y'all have been very helpful. especially William. that is probably my problem. although i do have a line g2d.dispose().
i will post some code when i am here at the library with my laptop.

Henry, maybe i just think the images are available for collection, i think they are. i will post some code when i can.
 
Jayesh A Lalwani
Rancher
Posts: 2762
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I might be wrong, but I'm looking at the API, and it seems like ImageStack does exactly what it says on the tin:- It keeps a stack of Images. So, if you add the image to the stack every time the mouse is released, the number of images in the stack would grow over time until you run out of memory

Not saying that there might be other memory leaks. But, this could be also a potential issue where your application will hog memory. This is something you wil run in C++ too. If you keep building images in a stack, you won't be able to release them, and then you will run OOM

 
Randall Twede
Ranch Hand
Posts: 4696
8
Java Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i'm sorry i did not realize java had a class called ImageStack. i wrote my own. when i first discovered this problem i did limit it to 50 images. i don't think that is the problem though(limiting it did not help). i think it is the intermediate images i create just to display in the JPanel, not the stack. i could be wrong, maybe even 50 images are too many.
 
Randall Twede
Ranch Hand
Posts: 4696
8
Java Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
what happens if the JVM finds two classes with the same name?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Randall Twede wrote:what happens if the JVM finds two classes with the same name?


Depends on the classloader. The "normal" ones just take the first one they find in the classpath. You could write your own classloader though that takes the last one, or throws an exception if the classpath contains multiple classes with the same name.

And note that for this question to make any sense, "name" has to mean "fully-qualified name." Two classes called "List" is not a problem for the JVM, as long as they're in different packages, though it might be confusing for a human programmer.
 
Anayonkar Shivalkar
Bartender
Posts: 1558
5
Eclipse IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Randall,

Java provides some excellent options and utilities to analyze such issues (OutOfMemoryError).

Personally, I prefer to use JVM option which gives a heap dump if OutOfMemoryError occurs (-XX:+HeapDumpOnOutOfMemoryError).

Further, this dump can be analyzed by jhat utility. This gives a nice overview of various objects and memory consumed by them (at the time of OutOfMemoryError).

Also, you can have exactly same package structure and same class name (in two separate jars). During such case, the class which appears first in classpath will be loaded by class-loader. However, it is not recommended to reuse same class names.

I hope this helps.
 
John Vorwald
Ranch Hand
Posts: 139
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
With enough "points" / lines, the code could run out of memory in mouseDragged. You may need to limit the number of points / lines to be added, or increase the amount of JVM memory available.
 
Randall Twede
Ranch Hand
Posts: 4696
8
Java Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
well, the Image Stack was the culprit. i tested it again. maximizing the program to make large images, and it added 49 of them before it ran out of memory
the ImageStack is for the undo button. nobody will hit that 50 times in a row, so 20 or 15, or even 10 will be ok
i should have never doubted the garbage collector. it is doing a fine job of cleaning up the temporary images. drawing freehand actually had nothing to do with the problem.
 
Jayesh A Lalwani
Rancher
Posts: 2762
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes this is why a lot of old school apps limited the number of times you could undo. There is just not enough space to keep the undo buffer

You might want to rethink your design a bit. Keeping the entire image in the undo buffer seems overkill. You can just keep a vector of points in your undo buffer, and redraw everything when the user undoes. OR you keep an image for every 10 items in the buffer, and the vector for the 10 items. If you refrain from keeping a huge stack of images, you will need less memory.

 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!