Skip to content
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 cannot collect unused AST nodes/Z3Object instances #44

Open
mtappler opened this issue Dec 29, 2014 · 2 comments
Open

GC cannot collect unused AST nodes/Z3Object instances #44

mtappler opened this issue Dec 29, 2014 · 2 comments

Comments

@mtappler
Copy link

Hello,

as far as I can tell, the garbage collector can only collect AST nodes, when the corresponding Context is deleted. This seams to be true for other Z3Object subclasses as well, but I am mentioning AST nodes explicitly, because this is the greatest issue for me.

The reason is that Z3Object instances get added to a Z3RefCountQueue object once they are created and this queue is not cleared until the context, which created the objects, is deleted. Hence, there is always a reference to an object, which might not be needed at all.

This became an issue while I was using Scala^Z3 for symbolic execution. During such executions I build lots of formulas for unsatisfiable paths, which are not needed in subsequent steps.
Since this led to severe problems regarding memory consumption, I had to switch to the Java-API, which is included in the master branch of Z3 at Codeplex (https://z3.codeplex.com/SourceControl/latest).

This API circumvents this problem by not keeping references from the context to the objects it created and overwrites Object.finalize() to get the reference counting in the C-API work correctly. So, the garbage collector can collect all formulas for unsatisfiable paths and the reference count of objects gets decremented correctly by the finalizer.

I think this should also work for this API.

@colder
Copy link
Member

colder commented Dec 29, 2014

We tried at some point to use finalize but it turned up to be highly unreliable for our needs. We (tried to) follow instead of C# api which uses a free-buffer that should periodically be checked and cleared. We relied more on a lot of small solvers that we end up freeing manually, so this might explain why the current way has worked out better than relying on finalize for us.

I will have a look at the alternative again.

@mtappler
Copy link
Author

I see. What exactly do you mean, when you say that finalize turned out to be unreliable? In my application, memory consumption rises from symbolic execution to symbolic execution, although it should not. More precisely, native heap size increases continuously.

Maybe this behaviour is also caused by unreliable finalize behaviour, which does not correctly decrement reference counters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants