GC in CrossNetRuntime/CrossNetSystem

Sep 18, 2008 at 4:52 AM
Edited Sep 18, 2008 at 5:00 AM
Hi there,

I'm the CTO of a software company that specializes in conversational AI techonogies.

The bulk of our codebase is C#/.NET, although we do have a minimal runtime in C++ that we maintain in parallel for tiny platforms.

Maintaining two codebases is a pain, considering that we need to have flawlessly identical behaviors within each version.


I've been looking at CrossNet as an interesting way to have our core code-base ENTIRELY written in C#, with auto-generated core for natively compiled runtimes.

Interestingly enough, after I spent some time beefing up your String and FileIO support, along with a couple of other elements, I can now auto-generate our core in its entirety.  I have a couple of tasks to complete regarding Lua integration to match our original cores, but on the whole, I now have what I was looking for.

Let me clarify: I am now at the point where I can build a working application around the CrossNet generated C++ version of our core, with NO hand tweaking of the C++ version.  As a side note, I also have it compiling into a linkable library, which would be very useful to us in terms of deploying an SDK.

Here is my question, and maybe it is too general, but how do I enable automated garbage collection within the context of the running application?

Your example benchmark application does recursive cleanup AFTER the benchmarks have executed, but I want to be able to periodically invoke GC within the context of the application.

I have some other questions about what seem to be memory leaks involving Strings and such, those can wait for another time.


Anyway, I feel like I am 95% of where I need to be with this, as our codebase works in its intirety with CrossNet.  I just need a little insight to get that last 5%, and would appreciate any help.

Also, I would be happy to give my CrossNet modifications back for you to integrate into the CrossNet codebase.  My FileIO enhancements, while functional for my purposes, is probably a little off-base in terms of how it should be implemented.  However, you can probably use my additions to the String library almost as-is.

Cheers,
Leslie
Coordinator
Sep 19, 2008 at 4:26 AM

Hi Leslie,
I'm glad that CrossNet works well for you!

About the garbage collection, it should run directly when the heap runs out of memory.
In the unit-tests, I run the GC after each test to make sure the previous test doesn't impact negatively the next test.
Some benchmark tests are running out of memory on purpose to stress-test the GC.

The way it works is that when we detect that we don't have enough memory, we call GCManager::Collect() - you can see the call at the end of GCAllocator::Allocate().
There is a trick though, if you collect in the middle of function calls, all the managed pointers stored locally will not be traced correctly as they will be stored on the stack.
The resolution is "relatively" easy.
You have to consider that all the CPU registers and the whole stack can point to collected objects (and you actually have to quickly determine if a pointer is a managed object or not to trace it).
The code is done in GCManager::TraceStack() with a very little bit of assembly code (so it has to be adapted depending of the platform).
Also we have to parse the whole stack from top to bottom (you can limit the upper side) as we don't control the generated code from the C++ compiler, so we can't tell that a particular variable on the stack is a managed pointer or not. CrossNet is taking care of most of that though, you pretty much just need to provide ways to list the registers and the beginning / end of the stack.
Without providing this piece of code, you will only be able to call the GC explicitly on some "safe" points where you know that there is no local managed pointers in the stack.

I didn't test extensively the String library so I'm not that surprised that there are some leaks in some pieces of C++ code. I focused mostly on the core framework.
Any improvement is extremely welcome! But I honestly don't know when I will do the next release as it depends of the level of interest from the community.

I really appreciate your help!
If you have any questions, don't hesitate to ask whether it's high or low level, I'll be happy to help you!

Regards,
Olivier