В моем Java-коде я вызываю Z3 в цикле, чтобы проверить формулу (которая зависит от индекса цикла и отличается для каждой итерации), пока формула не станет выполнимой, как указано в следующем фрагменте псевдокода:Z3 Java API: когда нужно размещать выражения/объекты Z3?
Тем не менее, я быстро сталкиваюсь с проблемами памяти (т. Е. Вызывается Z3Exception
с сообщением «из памяти»), и я чувствую, что я, вероятно, неправильно размещаю созданные Z3Objects.
Поскольку я не нашел информации об этом (я только что нашел Z3 Java API documentation or tutorial и Performance issues about Z3 for Java), мои вопросы:
- При вызове
solver.dispose()
, все содержащиесяBoolExpr
расположены так или мне нужно помнить о них где-то и звоните.dispose()
на любой из них? - Было бы более сложно перенести создание и удаление контекста и решателя из цикла и вместо этого использовать
solver.push()
иsolver.pop()
внутри цикла? - Что еще
Z3Objects
должен ли я «вручную» в данном случае?
Thanks Christof. Вызов сборщика мусора немного улучшает проблему. Однако, когда я использую один экземпляр контекста/решателя (вместо того, чтобы создавать его на каждой итерации) и вызывать 'push' /' pop', программа suddently показывает низкий профиль памяти. Это, похоже, решает мою проблему, но может ли это указать на утечку в Java API? – Dan
Не уверен, что я понимаю. Использование инкрементного решателя (т. Е. Использование push/pop) действительно влияет на поведение решателя; во многих случаях Z3 переключается на совершенно другой решатель, который поддерживает инкрементное решение (которое часто медленнее для одного конкретного запроса, но иногда быстрее). Некоторые вещи сохраняются в памяти через вызовы push/pop (например, символы), это то, что вы называете утечкой? –
Использование push/pop прекрасно работает в том, что он не исчерпывает память. Создание нового решателя и его удаление после одного запроса очень скоро заканчивается из памяти (даже при вызове сборщика мусора). – Dan