Является ли память скомпилированных/оцененных процедур сборщиком мусора в Chez Scheme?

Многие, возможно, большинство языковых реализаций, которые включают компилятор во время выполнения, пренебрегают сборкой мусора отбрасываемого кода (см., например, julia, где этот приводит к утечке памяти в таких приложениях, как генетическое-программирование)

Мои предварительные тесты показывают, что в Chez Scheme нет утечки памяти, но я хотел бы знать это с большей уверенностью, так как я даже не знаю, компилируются ли f и g на самом деле. (Старая мантра: тесты могут доказать только наличие ошибок, а не их отсутствие)


Тест, который я попробовал: f и g вызывают друг друга, и их определения заменяются во время выполнения.

(define f)
(define g)

(define (make-f x)
  (eval `(set! f (lambda (y)
           (if (> y 100)
             (+ (remainder ,x 3) (g y))
             (+ y 1))))))

(define (make-g x)
  (eval `(set! g (lambda (y)
           (if (< y 10)
             (+ (remainder ,x 5) (f y))
             (div y 2))))))

(define (make-and-run-f n)
  (begin
    (make-f 1)
    (make-g 1)
    (let loop ((i 0) (acc 0))
      (if (> i n)
        acc
        (begin
            (make-f i)
            (make-g i)
            (loop (+ i 1) (+ acc (f 33))))))))

(time (make-and-run-f 1000000)) ; runs in 10 min and negligible memory

person bobcat    schedule 24.12.2020    source источник
comment
Ваш код define уже определил привязки, поэтому он не соответствует стандартной схеме, и результат недоопределен. Определите его на верхнем уровне и используйте set! в процедурах.   -  person Sylwester    schedule 25.12.2020
comment
@Sylwester Обновлено, спасибо. Я смутно помню, как использовал схему, которая не redefine. Гамбит? Массачусетский технологический институт? Из-за этого интерактивная разработка была громоздкой.   -  person bobcat    schedule 26.12.2020


Ответы (1)


Учитывая важность как процедур, так и сборки мусора для Scheme, я был бы удивлен, если бы Chez Scheme не пытался собирать мусор любые динамически созданные объекты. Стандарт R6RS гласит [выделено мной]:

Все объекты, созданные в ходе вычисления Схемы, включая процедуры и продолжения, имеют неограниченный размер. Ни один объект Scheme никогда не уничтожается. Причина того, что реализации Scheme (обычно!) не исчерпывают память, заключается в том, что им разрешено освобождать память, занимаемую объектом, если они могут доказать, что объект не может иметь значения для каких-либо будущих вычислений.

Процедура — это объект, и любой объект может быть удален сборщиком мусора, если реализация может доказать, что вычислениям он больше не понадобится. Это не обязательное требование, но это относится к любому объекту, а не только к процедурам.

Руководство Chez Scheme кажется окончательным, хотя (Руководство пользователя Chez Scheme версии 9, стр. 82):

Поскольку все объекты Scheme, включая объекты кода, могут быть перемещены или даже утилизированы сборщиком мусора....

В 1990-х Кент Дибвиг вместе с Дэвидом Эби и Карлом Брюггеманом написал статью, которая может быть здесь интересна, под названием Don’t Stop the BIBOP: Flexible and Efficient Storage Management for Dynamicly Typed Languages, описывающая стратегию сборки мусора, реализованную в Chez Scheme. В статье некоторое время уделяется обсуждению объектов кода и, в частности, тому, как они отделяются и по-разному обрабатываются в процессе сборки мусора (поскольку они могут содержать указатели на другие объекты).

person ad absurdum    schedule 24.12.2020