Let's say we have a Ruby class like this:

class MyClass
  def my_method(p)
     # do some cool stuff with a huge amount of objects 
     my_objects = ...

     return my_objects
  end
end

And somewhere else in the application there's a function that calls MyClass's my_method, pretty much like this:

def my_func
  #doing some stuff ..

  MyClass.my_method(some_param)

  #doing other stuff ..
end

What happens to the list of objects, is it eligible for garbage collection? Is it possible to know roughly when it's going to be collected?

Is there a way to "mark" the list as eligible for GC? Maybe like this:

def my_func
  #doing some stuff ..

  objects = MyClass.my_method(some_param)
  objects = nil #does this make any difference?

  #doing other stuff ..
end
有帮助吗?

解决方案 2

Items returned from the function are eligible for being collected once nothing else points to them.

So, if you ignore the return value and really nothing more remembers those objects, than yes, thay can be GC'ed.

So, if you store the result in objects variable, then the returned values will be 'pinned'**) as long as the objects variable still remembers them***). When you nil that variable, they will be released and pending for collection. Nilling that variable may speed up their collection, but does not necessarily have to. *)

UNLESS anything other still remembers them. If between the objects=f() and objects=nil you read the values from objects variable and pass them to other functions/methods, and if they happen to store those objects, then of course it will pin them too, and "nilling" will help a bit in releasing the resources but not cause any immediate collection.*)

(*) In general, in environments with GC, you never actually know when the GC will run and what will it collect. You just know that objects that were forgotten by everyone will eventually be automatically removed. Nothing more. Theoreticaly, GC may choose to not run at all if your machine has terabytes of free memory.

(**) in some environments (like .Net) "pinning" is a precise term. Here I said it like that just to help you imagine how it works. I do not mean real pinning of memory blocks for communication with lower-level libraries, etc.

(***) When where's an object A remembers object B which remembers object C, and if the "B" becomes forgotten and if only B (and noone else) rememebers the C, then both B and C are GC'ed. So, you don't have to nil the objects. If the thing that contains objects variable at some point becomes 'forgotten', then both the "outer thing", and "objects" and the "returned items" will be GC'ed. At least should be, if GC implementation is OK.

This leaves one more thing to say: I do not say about GC in Ruby 2.0. All I've said was about garbage collectors in general. It applies also to Java, .Net, ObjC (with GC) and others. If you need to know precisely what happens in Ruby 2.0 and what are the gory details of GC implementation - ask directly about that :)

其他提示

GC destroys all objects which are not being referenced by your code. By setting objects to nil, you change reference of the variable, hence objects will be GCed, but exactly same thing is going to happen if you go with the first code. The real question is - why do you need for this object to be GB at precise moment - it shouldn't affect your code at all.

If you really want to have better control over garbage collection you can look at GC class: http://www.ruby-doc.org/core-1.9.3/GC.html. Note that you can rerun GC.start, which will force GC to run at that precise moment (even if there is nothing to collect).

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top