boehm-gc: финализатор и сжатие до кучи

У меня есть 2 вопроса о Boehm-GC.

  1. Когда GC собирает мусорный объект, GC освобождает память без вызова деструктора, хотя у объекта есть деструктор. Я обнаружил, что GC называет «finailzer», но я не знаю, как его зарегистрировать … Как я могу это сделать?

  2. Когда GC собирает мусор, GC, кажется, не вызывает free () (или другую функцию освобождения памяти). Кажется, что GC не освобождает мусор, но помещает его в пул памяти GC и использует пул при следующем выделении. GC освобождает пул памяти во время простоя? Если нет, могу ли я сказать ГК «пожалуйста, освободите пул памяти»?

PS. Я не могу найти ссылку на boehm-gc. Не могли бы вы сказать, где находится ссылка?

1

Решение

Если вам нужно больше ссылок, чем указано в gc.h заголовочный файл, тогда вы, вероятно, должны прочитать о сборщиках мусора, прежде чем идти дальше.

Вы задаете вопрос, gc.h В заголовке есть то, что вам нужно:

typedef void (*GC_finalization_proc)
GC_PROTO((GC_PTR obj, GC_PTR client_data));

GC_API void GC_register_finalizer
GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,
GC_finalization_proc *ofn, GC_PTR *ocd));
GC_API void GC_debug_register_finalizer
GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,
GC_finalization_proc *ofn, GC_PTR *ocd));
/* When obj is no longer accessible, invoke     */
/* (*fn)(obj, cd).  If a and b are inaccessible, and    */
/* a points to b (after disappearing links have been    */
/* made to disappear), then only a will be      */
/* finalized.  (If this does not create any new     */
/* pointers to b, then b will be finalized after the    */
/* next collection.)  Any finalizable object that   */
/* is reachable from itself by following one or more    */
/* pointers will not be finalized (or collected).   */
/* Thus cycles involving finalizable objects should */
/* be avoided, or broken by disappearing links.     */
/* All but the last finalizer registered for an object  */
/* is ignored.                      */
/* Finalization may be removed by passing 0 as fn.  */
/* Finalizers are implicitly unregistered just before   */
/* they are invoked.                    */
/* The old finalizer and client data are stored in  */
/* *ofn and *ocd.                   */
/* Fn is never invoked on an accessible object,     */
/* provided hidden pointers are converted to real   */
/* pointers only if the allocation lock is held, and    */
/* such conversions are not performed by finalization   */
/* routines.                        */
/* If GC_register_finalizer is aborted as a result of   */
/* a signal, the object may be left with no     */
/* finalization, even if neither the old nor new    */
/* finalizer were NULL.                 */
/* Obj should be the nonNULL starting address of an     */
/* object allocated by GC_malloc or friends.        */
/* Note that any garbage collectable object referenced  */
/* by cd will be considered accessible until the    */
/* finalizer is invoked.                */

Итак, вы определяете обратный вызов:

typedef <any type at all you want passed to the callback
as data for its own use> MY_ENVIRONMENT;

void my_callback(GC_PTR void_obj, GC_PTR void_environment) {
MY_ENVIRONMENT *env = (MY_ENVIRONMENT)void_environment;
MY_OBJECT *obj = (MY_OBJECT*)void_obj;

// Do finalization here.
}

Создайте свою среду (если есть; в противном случае просто передайте NULL):

MY_ENVIRONMENT *my_env = new MY_ENVIRONMENT;
// Initialize if necessary.

Затем зарегистрируйте его на вновь выделенном объекте:

MY_
MY_ENVIRONMENT old_env;
GC_finalization_proc old_proc;
GC_register_finalizer(new_obj, my_callback, my_env, &old_env, &old_proc);

Сейчас my_callback будет вызываться с вашей записью среды, когда этот конкретный объект будет собран.

Что касается вашего вопроса 2, вы упускаете суть. Boehm GC заменяет malloc / new и free и управляет своей собственной ареной памяти. Обычно он сам решает, когда делать коллекцию. Это обычно, когда большая часть арены была израсходована. Сборка мусора идентифицирует блоки, которые свободны, следовательно, могут быть перераспределены. Как API заметки Ясно, что вы можете принудительно собирать и освобождать объекты, но они обычно не нужны.

3

Другие решения

Других решений пока нет …