strange garbage collection behavior.
a while ago I came across the strangest bug.
I was using rmxp and a bitmap to png script to process large amounts of images to which i need to perform repeated operations.
(it got the the point where I was processing hundreds of images) how ever. the first time i tried to do more than 100 images at once, I got an error that it could not accesses a file the clearly existed and was not in use.
so I added
inside the loop for each image after the disposal. and THEN it worked.
I thought that this was strange that the garbage collection didn't happen automatically so I removed the line and tried again, I got the error again
could it be the GC modal doesn't start until we TELL it to?
How did you create the images?
The garbage cleaner has its own life.
You can start it explicitly which generally is a bad idea, but can help if you loose reference to a large amount of objects.
In your case I believe the problem is that you don't dispose some (all?) of the images before loosing the reference too them.
well it was in a loop that looked like this
def self.resize
GC.enable
unless FileTest.directory?("resize")
Dir.mkdir("resize")
end
for i in 1..493
if (i % 50) == 0
GC.start
Graphics.update
end
if FileTest.exists?("Graphics/Pictures/start/#{i}.bmp")
start_bitmap = RPG::Cache.picture("start/#{i}.bmp")
w = start_bitmap.width
h = start_bitmap.height
new_bitmap = Bitmap.new(w + (w * 0.5) , h + (h * 0.5))
src_rect = Rect.new(0, 0, w, h)
dest_rect = Rect.new(0, 0, w + (w * 0.5) , h + (h * 0.5))
new_bitmap.stretch_blt(dest_rect, start_bitmap, src_rect)
new_bitmap.make_png("#{i}", 'resize/')
new_bitmap.dispose
start_bitmap.dispose
new_bitmap = start_bitmap = nil
end
end
end
but until I added the GC.enable it would give me an error about half way through about not being able to access a file the DID exist and was not in use by anything. I guess i could of gotten by without the GC.start thought.
Actually I would recommend not to mess with the GC. :/ It's enabled and started by default.
I suggest that you do not put it in the since you are just going to throw it away.
Instead use Bitmap.new(filename).
Note also that your way does not work with encrypted archives as FileTest.exists? will not detect files in the .rgssad.
Yeah, I don't worry about Garbage Collection. He just comes early morning every Wednesday and takes it for me. :)
normally I would leave the GC as is, however in this instance where i was using rgss to process bitmaps to make them into usable sprite and not have to photoshop 400+ images just to resize and align them. the script failed about 75 images in, and didn't work UNTIL i mess with the GC. I was just wondering if there was a reason I even had to touch the gc when it normal works.
75 images? What dimensions were they?
384*32
That's about 9 MB of memory. There's no way that you ran out of RAM. :/
Quote from: ForeverZer0 on August 05, 2010, 04:52:18 pm
Yeah, I don't worry about Garbage Collection. He just comes early morning every Wednesday and takes it for me. :)
ROFL! *level up*
You're a genius!
well while i was reconstructing the RPG::Cache class to work for RMPY I noticed this
def self.clear
@cache = {}
GC.start
end
is it called there just to make sure that everything is collected? or is it called because otherwise it is never run?
Honestly, I'm not sure myself. This starts the GC in general. When it's active, it keeps doing its job when it feels like it. Now, I'm not sure if calling start forces the GC to clear all garbage that has been collected up to that point. And I don't remember if the Ruby documentation explained it either.
well if it dose the same thing that pythons gc.collect dose it makes sense
first off you would really only clear the cache when exiting and when youe do you cut refrence to a ton of large objects so it would make sense that you would want to gc them asap.