/> 忍者ブログ

WEEKEND ECONOMIST

小さな工夫と発見の蓄積

R6 Class とオブジェクトの破棄

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

コメント

ただいまコメントを受けつけておりません。

R6 Class とオブジェクトの破棄

プログラム言語によっては、変数やオブジェクトが不要になったときには、kill や dispose などのメソッドを使って明示に破棄する必要があり(または推奨されていて)、これを怠るとメモリリークの原因となりパフォーマンスに影響する(らしい)。

Rでは、このあたりの管理はシステム任せでよくて、オブジェクトの破棄について気にする必要はない。ところが、最近 R6 という直感的にオブジェクト指向なコーディングを可能にするライブラリについて教えてもらい、自分自身も使い始めた。クラスインスタンスを生成したり参照したりしていたら、ふと「参照されなくなったオブジェクトはどう処理されているんだろう」と不安になった。まさか忘れられたインスタンス達が散乱しているのでは、という懸念だ。

答えは公式の導入ページに書いてあった。不要になった(参照されていない)クラスインスタンスは、通常通り自動的にごみ収集機能(Garbage Collection)によって破棄される。関数 gc() を呼べば強制的にごみ収集を発生させることができるが、gc() のヘルプによると不要らしい。

下のコードでは、ごみ収集の機能をテストしている。
A クラスは、数字ひとつを要素にもつクラスだ。公式の例を参考に、生成時に reg.finalizer() 関数を使ってインスタンスが破棄された時の動作を「登録」している。ここでは格納された数字を表示させることによってどのインスタンスが破棄されたのかが分かるようにしている。

3つのAクラスインスタンスからなるリストを生成して、rm() により破棄すると、3つ全てが不要になりごみ収集対象になる(この時、rm() の前に一度 gc()を施しておくことで、破棄の結果だけを切り離している。こうしないと、インスタンス生成時に発生したゴミがまだ残っていて、同時に破棄されることがある)。

同じように3つのAクラスインスタンスからなるリストを生成して、今度は3つのうち1つ目の要素だけ削除する(参照を外す)。すると、削除された要素だけがゴミとみなされる。さらに、要素のうちの1つを別の変数により参照してからもとのリストを削除すると、参照されているインスタンスはまだ使用中ということになるから、ゴミ収集対象にならない。

結論としては、ごみの選別はきっちりやってくれているらしいから、メモリの心配はあまりしなくてよさそうだ。
library(R6)

A <- R6Class('A',
    public = list(
        number=NA,
        initialize = function(number) {
            self$number <- number
            reg.finalizer(
                self,
                function(e) cat('Garbage collected! #', e$number, '\n'),
                onexit = TRUE
            )
        }
    )
)

a <- list(A$new(1), A$new(2), A$new(3))
gc()  # clean up the garbage created when initializing

# when the list is removed, all three instances are 'garbage'
rm(a)
gc()
#Garbage collected! # 3
#Garbage collected! # 2
#Garbage collected! # 1
#    used (Mb) gc trigger (Mb) max used  (Mb)
#Ncells 567894 30.4    1168576 62.5  1168576  62.5
#Vcells 821924  6.3    2994598 22.9 54470995 415.6


a <- list(A$new(1), A$new(2), A$new(3))
gc()
# remove the reference to the 1st element.
a <- a[-1]
gc()
#Garbage collected! # 1
#    used (Mb) gc trigger (Mb) max used  (Mb)
#Ncells 567896 30.4    1168576 62.5  1168576  62.5
#Vcells 821917  6.3    2994598 22.9 54470995 415.6

# let another variable refer to the first element
b <- a[[1]]
rm(a)
gc()
#Garbage collected! # 3 
#    used (Mb) gc trigger (Mb) max used  (Mb)
#Ncells 567879 30.4    1168576 62.5  1168576  62.5
#Vcells 821913  6.3    2994598 22.9 54470995 415.6
PR

コメント

プロフィール

HN:
KM
性別:
非公開

カレンダー

05 2025/06 07
S M T W T F S
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30