gc interactions (performance, not correctness)

0 views
Skip to first unread message

Steven Parkes

unread,
Feb 20, 2010, 2:44:59 PM2/20/10
to johnso...@googlegroups.com
I'm wondering what the best way is to make "global GC", i.e., the combined GC, work best.

One thought is to make the SM collector call the Ruby collector. But I'm not sure how effective that is. I'm guessing what I'm seeing is that very little garbage in Ruby land can create dumpsters of garbage in Spidermonkey land. I'm not sure if the Ruby collector will actually do anything if it doesn't think there's much to do.

I've definitely seen cases where it refuses to collect things, but it might thing there are live references in scope (temporaries or ghosts?)

In fact, in the capybara tests, this particularly hairy because the default mechanism is to create a new runtime for every test. I can change this, but before I do, I want to make sure I understand it and see if there are other things we should add.

The fundamental problem I'm seeing is that I seem to never be able to cause those runtimes to be destroyed (as defined by calling the ext deallocate function). I nil out the reference and call GC.start but that doesn't get me anywhere. Still doesn't call deallocate until right before exit.

If anybody who knows more about the Ruby collector than I do (which would be almost anyone) has any ideas ...

I've been toying with either a #destroy or a #reset. #destroy would destroy the runtime and, presumably, remove all methods from the object so you couldn't mistakenly try to use it more. #reset would destroy the runtime but recreate it so you could continue to use it. In the case of the env.js stuff, I'd want to make the recreation lazy since it's not cheap.

Suggestions?

Aaron Patterson

unread,
Feb 20, 2010, 3:12:36 PM2/20/10
to johnso...@googlegroups.com
On Sat, Feb 20, 2010 at 11:44 AM, Steven Parkes <smpa...@smparkes.net> wrote:
> I'm wondering what the best way is to make "global GC", i.e., the combined GC, work best.
>
> One thought is to make the SM collector call the Ruby collector. But I'm not sure how effective that is. I'm guessing what I'm seeing is that very little garbage in Ruby land can create dumpsters of garbage in Spidermonkey land. I'm not sure if the Ruby collector will actually do anything if it doesn't think there's much to do.
>
> I've definitely seen cases where it refuses to collect things, but it might thing there are live references in scope (temporaries or ghosts?)
>
> In fact, in the capybara tests, this particularly hairy because the default mechanism is to create a new runtime for every test. I can change this, but before I do, I want to make sure I understand it and see if there are other things we should add.
>
> The fundamental problem I'm seeing is that I seem to never be able to cause those runtimes to be destroyed (as defined by calling the ext deallocate function). I nil out the reference and call GC.start but that doesn't get me anywhere. Still doesn't call deallocate until right before exit.

Yes, I'm not surprised. We store the runtime context in the current
thread. The runtime context keeps a reference to the runtime. If the
current thread is the main thread, the runtimes probably won't get
GC'd (right now).

Take a look at:

lib/johnson/spidermonkey/runtime.rb

def current_context
contexts = (Thread.current[CONTEXT_MAP_KEY] ||= {})
contexts[self.object_id] ||= Context.new(self)
end

I don't remember exactly why we need this. O_O

--
Aaron Patterson
http://tenderlovemaking.com/

Steven Parkes

unread,
Feb 20, 2010, 4:04:52 PM2/20/10
to johnso...@googlegroups.com

On Feb 20, 2010, at Feb 20,12:12 PM , Aaron Patterson wrote:

> Yes, I'm not surprised. We store the runtime context in the current
> thread.

Yup, that was it.

I think I kinda understand why it's in there: you need a context-per-thread when you're trying to do multithreaded stuff with SM.

But, of course, Ruby 1.8 threads aren't real threads. And we don't think (I think) 1.8 threads interact well with SM anyway. And there's lots of talk about the thread support in SM really not being usable even if we had kernel threads.

So I'm planning on yanking this out. I'll leave in code to make sure we only access the context from the "spidermonkey" thread (which is as close as we might get to supporting threads in 1.8, I think).

I thought about doing it right by maintaining the map in the runtime and just keeping a key map in the thread. But if we did have threads, that requires mutexes etc and this is in a pretty critical path, so I can't see it being worth the value until we really think we can support some form of threads.

Aaron Patterson

unread,
Feb 20, 2010, 4:10:27 PM2/20/10
to johnso...@googlegroups.com
On Sat, Feb 20, 2010 at 1:04 PM, Steven Parkes <smpa...@smparkes.net> wrote:
>
> On Feb 20, 2010, at Feb 20,12:12 PM , Aaron Patterson wrote:
>
>> Yes, I'm not surprised.  We store the runtime context in the current
>> thread.
>
> Yup, that was it.
>
> I think I kinda understand why it's in there: you need a context-per-thread when you're trying to do multithreaded stuff with SM.
>
> But, of course, Ruby 1.8 threads aren't real threads. And we don't think (I think) 1.8 threads interact well with SM anyway. And there's lots of talk about the thread support in SM really not being usable even if we had kernel threads.
>
> So I'm planning on yanking this out. I'll leave in code to make sure we only access the context from the "spidermonkey" thread (which is as close as we might get to supporting threads in 1.8, I think).

That sounds good to me. We have tests for this stuff anyway, so if
you do it wrong, the tests should explode. ;-)

Reply all
Reply to author
Forward
0 new messages