Hi,
I've been tracking down what seemed to be a memory leak in a large program written using Termite. The image was growing to over 500Mb for no obvious reason and after a lot of hunting the problem seems to lie with the use of spawned processes to model mutable structures. The example code from the paper on the Termite site as below
(define (make-cell content) (spawn (lambda () (let loop ((content content)) (recv ((from tag 'ref) (! from (list tag content)) (loop content)) (('set! content) (loop content)))))))
(define (cell-ref cell) (!? cell 'ref))
appears at first glance to be tail recursive. However, the example below
(define (cell-set! cell value) (! cell (list 'set value)))
(define c (make-cell (make-vector 10000)))
(define v (vector->list (make-vector 100000 -3)))
(define (ctest) (map (lambda(i)(cell-set! c (make-vector 1000 -2))) v))
(ctest)
will run a heap of 200Mb out of space. I assume recv is a macro which generates non-tail callable code. So after a large number of accesses o a cell memory is eaten up by the loop recursing.
Is there any way around this? Or have I made a mistake esp. since named lets seem to be very common in Termite code. I would have used define-structure and worked around side effecting code except structure types appear not be equivalent between Termite instances ie defined structure A on instance X is not the same objects defined using the same structure A but created in a separate instance B. Accessing A objects created on X but passed to B result in a type exception.
Nick Walton
Afficher les réponses par date