■
厳密でなくてもいいなら、eval/svと(gc-stat)を使えば、擬似的にメモリ使用量を制御できる事に気付いた。
(use eval-sv) (use gauche.parameter) (use util.list) (define-values (eval/sv env) (make-eval/sv :isolate-port? #f)) (define original-size (make-parameter #f)) (define limit-size (make-parameter #f)) (define (get-used-memory) (let1 stat (gc-stat) (- (car (assoc-ref stat :total-heap-size)) (car (assoc-ref stat :free-bytes))))) (define (sv type symbol expr args return except) (define (over?) (let1 mem (get-used-memory) (< (+ (original-size) (limit-size)) mem))) (when (over?) (gc) (when (over?) (except "out of memory" (get-used-memory)))) (apply expr args)) (define (eval/memlimit expr limit) (gc) ; これが無いと正しく測定できない (parameterize ((original-size (get-used-memory)) (limit-size limit)) (eval/sv expr sv)))
試してみる。
(eval/memlimit `(let baibain ((kuri-manjuh '(1))) (display (length kuri-manjuh)) (display " ") (display (,get-used-memory)) ; for debug (newline) (baibain (append kuri-manjuh kuri-manjuh))) 10)
1 3665920 2 3665920 4 3665920 8 3665920 16 3665920 32 3665920 64 3665920 128 3665920 256 3665920 512 3665920 1024 3665920 2048 3665920 4096 3665920 8192 3665920 16384 3665920 32768 3665920 *** ERROR: out of memory 3780608 Stack Trace: _______________________________________
何度か試してみたが、kuri-manjuhが65536個になるまで終了しない。
その時のメモリの変化量は114688。
一応機能はしているものの、なかなか大雑把だ。
どうしたものか。
他の問題点としては、S式バトラーのように、複数のevalを同時に起動して、継続を使ってコルーチン的に動きまわるような場合には、正常にメモリ使用量を取る事が出来ない。
これはちょっと困る。
とは言え、単純にeval/svが入れ子になる場合に対しては正しく機能する筈。
これは……微妙だ。
どうしよう。
もう少し考えよう。