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))

メモリを自動的に再利用したいのですが、どうすればよいですか? 私はメモリのファイナライズに関するドキュメントを見てきましたが、それがどのように役立つのかわかりません。とにかく、各関数を手動で呼び出す必要はありませんか?

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 に答える