-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GC behaviour #96
Comments
It might be the memory pool reservation. I notice when I hit return the first few times there's a small delay, but after that, it's much faster - probably because it now has a big chunk of memory ready for new objects. If you create a Type and Print something from the Delete() method, you'll see that things are getting freed as you might expect - but obviously there's a lot of memory pre-allocated in the pool. I haven't found any functions yet, which might be used to shrink it back down. |
Yes and that's fine in principle - but not when that chunk takes up all available RAM or more, freezing the entire PC (and causing a wait of half a minute long afterwards every time I click on another program because its memory had to get pushed to the harddrive). |
Seems others have similar issues: Some there state that the GC collects stuff after two cycles. First "finalizes" and second "frees". So you might try to call GCCollect twice in your loop |
The two-cycle thing should only apply to objects with finalizers, which byte arrays don't have, so that can't be it. Plus, I ran 6+ iterations in every test; and normally |
I've committed some updates to the GC settings. Hopefully that will help a bit. |
And an update to Boehm GC 8.0.4 |
I've tested this a bit more, but haven't really come to any definite conclusions. It's quite possible that my test program is flawed - possibly due to its high frequency of large allocations? The GC might be trying to estimate much much memory the program might need based on past allocations and be thrown off by this. Adding a sufficient amount of smaller allocations inbetween appears to improve the behaviour; but it's hard to tell for sure, since test results vary. I suppose trying to test GC performance with small sample like this might be a bad idea. That said, I've noticed something else: Test code (with topological ordering, only
|
That seems better. Thanks. But it may raise issues elsewhere, that may rely on Delete() occurring in a predictable way... |
Maybe this is an encouragement to utilise IDisposable where appropriate :-) |
It seems that the garbage collector used in NG is extremely aggressive in allocating memory and reluctant to return or reuse it.
I've written the following test program calls a function
F
that allocates a gigabyte of memory for a local variable which becomes unreachable as soon as the function returns. Then it runs the GC, prints some info to the console and waits for input before running the next iteration:When run in vanilla BlitzMax on my laptop (starting out with a RAM usage of ~3.5GB out of 8GB), the program produces output that looks like this:
This is the computer's RAM usage during that time:
Memory comsumption here shows little spikes, which immediately disappear again. Evidently, vanilla's GC promptly returns the garbage memory that was allocated by F in every iteration (presumably the slightly negative "left over" values from the 2nd iteration onward are due to the strings being passed to
Print
andInput
getting reclaimed as well), and overall memory consumption between iterations stays constant.On the other hand, this is the output for NG:
There is some weirdness in the console output caused by the fact that
GCMemAlloced
andGCCollect
returnInts
when they should be returningSize_T
, but that aside:Apparently, NG at first neither returns nor reuses the memory allocated for the array, and instead keeps allocating more. It only starts collecting once it has exhausted all available RAM; at times causing freezes on the order of multiple seconds up to tens of seconds for itself and any other program as the computer starts trying to make room for it by swapping memory between RAM and hard disk.
I am not expecting NG to behave exactly like vanilla does, and I could understand the GC holding on to some memory to make future allocations more efficient. But the current behaviour is akin to a memory leak, which is ...very bad. Is there a way to get the GC to behave itself?
The text was updated successfully, but these errors were encountered: