2

我有一个到 C 库的绑定。

(define-cstruct _rect
  ([x _int]
   [y _int]
   [w _int]
   [h _int]))

我想在程序中使用这个对象。

(require ffi/unsafe
         (rename-in "sdl-structs.rkt"
                    [make-rect _make-rect]))

(module rect racket
  (provide (all-defined-out)))

(define (make-rect x y w h)
  (define new-rect (_make-rect x y w h))
  new-rect)

(define (left rect)
  (rect-x rect))

(define (top rect)
  (rect-y rect))

...

(define (bottom-left rect)
  (values (left rect) (bottom rect)))

(define (bottom-right rect)
  (values (right rect) (bottom rect)))

但目前存在内存泄漏。崩溃需要一段时间,但它仍然会崩溃。

(define (eat-memory)
  (define memory (current-memory-use))
  (define (eat-loop)
    (begin
      (make-rect 0 0 1 1)
      (displayln memory)
      (set! memory (current-memory-use))
      (eat-loop)))
  (eat-loop))

我想让内存自动回收,我该怎么做呢?我查看了有关 finalization of memory 的文档,但我不明白这应该有什么帮助。反正我不需要手动调用每个函数吗?

4

1 回答 1

2

这是您的代码的核心,没有额外的噪音:

#lang racket
(require ffi/unsafe)
(define-cstruct _rect ([x _int] [y _int] [w _int] [h _int]))
(let loop ([n 0])
  (make-rect 0 0 1 1)
  ;; (list 0 0 1 1)
  (displayln (current-memory-use))
  (loop (add1 n)))

如果你运行它,你会看到看起来像泄漏的东西。现在翻转要使用的评论list,您会看到类似的泄漏。问题是您在每次分配后打印内存使用情况,并且需要很长时间才能达到 GC 开始工作的点。如果您更改它以减少打印输出的频率,您将看到稳定的内存。这是我跑来看这个的:

#lang racket
(require ffi/unsafe)
(define-cstruct _rect ([x _int] [y _int] [w _int] [h _int]))
(let loop ([n 0])
  (make-rect 0 0 1 1)
  (when (zero? (modulo n 100000)) (displayln (current-memory-use)))
  (loop (add1 n)))

话虽如此,当您使用不安全的 FFI 时很容易发生内存泄漏,并且您使用的库本身可能存在问题,毕竟,可能还有其他一些错误......

于 2013-08-10T15:09:51.313 回答