So, while reading the RGSS3 documentation, I came across a part of the index that I seem to not have seen in many scripters' codes, so I really don't know what it fully means.
What is GC / Garbage Collection? I've just read that this is a module (GC): A module that controls garbage collection in the Ruby interpreter.
However, I want someone to explain what really it is for, what it does and how it affects the gameplay. If possible, I want it to be explained to someone like me who isn't really knowledgable enough in programming or in other words, a newbie.
Garbage Collection in RGSS3
● ARCHIVED · READ-ONLY
-
-
From what I know,GC is disposing of classes automaticlly without adding the
Code:def dispose() end -
To put it simply, everything that's created in Ruby has to live in your computer's memory. Once it's no longer needed, it's good to delete it from memory so that your memory doesn't fill up. If your memory did fill up, your game would run very, very slowly. What garbage collection does is when it find something that's no longer being used, it deletes it. This is all handled internally by Ruby, so you won't really "see" it. But it's important because it keeps your games running smoothly.
-
Does that mean that if there are undisposed sprites and planes out there on a script, the Garbage Collection can handle all of those and remove it when they're not disposed at the right scene or window?To put it simply, everything that's created in Ruby has to live in your computer's memory. Once it's no longer needed, it's good to delete it from memory so that your memory doesn't fill up. If your memory did fill up, your game would run very, very slowly. What garbage collection does is when it find something that's no longer being used, it deletes it. This is all handled internally by Ruby, so you won't really "see" it. But it's important because it keeps your games running smoothly.
-
Yes. That is the presumption. Various aspects of computers and software have their own amount of control of the process....
An operating system such as Microsoft Windows does quite a bit of this in its idle compute cycles, managing memory. The Ruby core system does a bit more of this, insofar as what's running in the Ruby parts. And finally, Ruby modules and classes could *theoretically* handle some of it themselves; though this is generally not warranted, unless and until one knows what one is doing....
(Although, I haven't seen the internal workings of the Ruby scripting engine; and I know of an "Open RGSS" project, in an attempt to make a replacement for Enterbrain's DLL/RGSS -- though I don't know if ORGSS does memory management like RGSS or lets the Ruby system do it....) -
But how does Garbage Collection know which ones are undisposed? Say for example, I made a plane in a certain Scene:
class Scene_XCommand < Scene_MenuBase def start super create_graphics end def create_graphics() @xgraphic = Plane.new @xgraphic.bitmap = Cache.picture("MyPicture") endendSupposing this is my new command, so the graphics appears and then, I wanted it to be disposed by the Garbage Collection thing, how can I set that up? -
Graphical object should explicitly disposed. Like Plane, Window, Sprite and Viewport (Bitmap will disposed automatically AFAIK)
Ruby Garbage Collection doesn't handle those things -
As TheoAllen said,you need to dispose of the sprite,plane,or viewport in the "terminate" method...That's what I do anyways...I don't rely heavily on GC,so sometimes,I dispose of stuff manually.
-
GC looks for objects that no longer have any references to them, and then gets rid of them. So, if I did the followingBut how does Garbage Collection know which ones are undisposed? Say for example, I made a plane in a certain Scene:
class Scene_XCommand < Scene_MenuBase def start super create_graphics end def create_graphics() @xgraphic = Plane.new @xgraphic.bitmap = Cache.picture("MyPicture") endendSupposing this is my new command, so the graphics appears and then, I wanted it to be disposed by the Garbage Collection thing, how can I set that up?
$my_object = My_Object.new$your_object = Your_Object.new$my_object = nilGC.start # Force GC to runGC would look at My_Object and see that it no longer has any references to it and would delete it but when it got to Your_Object it would see that it's still referenced by the global variable $your_object and would leave it alone. -
To put it simply, there are two worlds when looking at the whole of Ruby. There is C world (where all the lower level stuff and the API comes together) and then you have Ruby world, where we work.
We as programmers have the ability to write C code in C world, and then expose it to Ruby world. This is what enterbrain did with Sprite, Bitmap, Tilemap, etc. This also means that they wrote different allocate / free method for these object. So no, Ruby does not handle these objects. All Ruby does is remove the string connecting these objects to Ruby world, meaning that any bitmaps not disposed are now essentially 'stuck in limbo.'
Ruby's GC is notoriously lacking, but it gets (most) of the job done. It depends on the programmer who implemented the extension whether or not memory management on what is exposed to Ruby world is efficient or not.
More simply put, Ruby GC cuts the string that ties C world stuff to Ruby world. It doesn't matter if underlying data is free'd or not; if the reference count on the object reaches zero, you have a memory leak. -
Short version: you mainly don't need to worry about what Ruby GC is doing and how, because you have little to no control over it through Ruby. You can 'suggest' to Ruby to begin garbage collection with GC.start, and you can 'protect' any object from being GC'd so long as it has any variable referencing it accessible from the current scope (including any available closures). Telling GC to start gives it priority, which may mean a temporary performance hit, and usually, the objects you are dealing with do not have enough of a memory footprint to warrant trying to "steer" the GC like that. Generally speaking, you are better of just letting it do what it does without trying to interfere.
However, when it comes to dealing with graphical objects (Sprite, Window, Plane and Viewport) it is very important that you use dispose to free the metadata of the object before you lose the last reference to the object to have it be GC'd because you may have not just a memory leak, but a potential Game.exe crash on your hand (see my sig thread). Windows stored in instance variables of Scene_Base and its descendants are disposed in the dispose_all_windows method when the scene terminates, everything else needs to be explicitly disposed. Bitmaps have not been shown to cause a crash if you don't dispose them, but you will have a very small memory leak (though bitmaps themselves seem to be inherently leaky). You do not need to dispose bitmaps loaded through Cache - these have a global reference and will never be GC'd. Calling .dispose does not free all memory associated with these objects, it frees the only metadata associated with the "hidden" methods; the Ruby object itself sticks around so long as it has a reference but it can no longer access any of these methods because the associated memory has been freed. Ruby GC will actually get most of the metadata associated with a Bitmap when it claims the object, but there is a very small difference in memory usage from disposing and having a bitmap be GC'd versus just having it be GC'd. The Ruby objects themselves are very small and don't warrant explicitly calling GC.start. -
Thank you very much for explaining all these to me. It's a big help for me to understand how all of these work. Enjoyed exchanging thoughts with you all.