前のエントリで書いたメモリリークを修正したText::CSV_XS 0.37がリリースされたみたいですよ

メンテナのMerijnと何回かメールのやりとりをした。このメモリリークの根源は前のエントリで書いた通りだったのだけれども、それと連動する形でgetline()を使った時にmeta_info()が仕様通りに動かないというバグがあった模様。これを直すとメモりリークも直ったとの事。

このフィックスを見てはたと気づいたのだが、sv_2mortal()しないでも、new(SV|AV|HV|RV)した変数は他のコンテナに関連づけると(格納すると)メモリ解放が自動的に行われるのだったな。

例えば
my %h = ( a => 1, b => 2, c => 3 );

こんな状況の場合、値側の1, 2, 3はそれぞれSV なわけだが、%hが自分の子要素として1, 2, 3が存在するのを知っている状態なので、%hのリファレンスカウントを--した時(SvREFCNT_decが呼ばれた時)に同時に1, 2, 3にもそれぞれリファレンスカウントがひとつ下げられる。その時にメモリ解放が行われる。

これらのSVを作る時にnewSV()しただけでsv_2mortal()もせず、%hにも格納しなければ、これらのSVはリークする。なぜなら、newSV()した時点でREFCNTは1で、それをSvREFCNT_dec()しないとメモリ解放されないのに、mortal化もされてないからだ。これがText::CSV_XS 0.36の状態。

Text::CSV_XS 0.37の場合はこのリークしていた変数に対して明示的な解放が行われるケースと、$selfに該当するハッシュに格納されるケースが追加された。これで必ずメモリ解放が行われるのでリークもない、ということだ。

Happy CSV parsing.