[#18440] racc segv revisited — "Akinori MUSHA" <knu@...>

 次のバグの件なんですが、現時点では原因究明を含めて未解決という

24 messages 2002/10/02
[#18617] Re: racc segv revisited — "Akinori MUSHA" <knu@...> 2002/11/02

At Wed, 2 Oct 2002 23:19:59 +0900,

[ruby-dev:18428] Re: shrink memory

From: matz@... (Yukihiro Matsumoto)
Date: 2002-10-02 04:53:59 UTC
List: ruby-dev #18428
まつもと ゆきひろです

In message "[ruby-dev:18427] shrink memory"
    on 02/10/02, nagai@ai.kyutech.ac.jp <nagai@ai.kyutech.ac.jp> writes:

|一つには TkcItem#delete において,管理用のハッシュからの情報削除の際,
|nil を代入するようにしていたという bug が原因でした.
|
|# これは Hash#delete を使わないといけないですよね.
|# 手が空いている方がありましたら,修正して commit していただけると
|# 助かります.

了解です。あやしいところを一括で修正しました。
まず1.7.3でコミットしますので、まずいところがあればどなたか
指摘してください。修正を添付しておきます。

|ですが,これを修正しても,Ruby は多量のメモリを占有したままです.
|ご存知の方はご存じの通りの体調ですので,
|きちんとした問題追跡やデバッグは行っていないのですが,
|結局のところ,ウィジェットパスとオブジェクトとの対応を
|管理するハッシュが一時的に肥大化して大量のメモリを要求し,
|それが不要 ( 管理ハッシュがほぼ空 ) になっても
|Ruby がそのメモリを確保したままになっているということのようです.
|
|例えば irb などで
|-------------------------------------
|h = {}
|(1..1000000).each{|i| h[i] = i}
|(1..1000000).each{|i| h.delete(i)}
|h = nil
|GC.start
|-------------------------------------
|などとやっても 24MB ほどのメモリを確保したままとなります.
|
|で,本題なのですが,「当面はこれ以上のメモリは必要としないよ」
|という状況で,余っているメモリを解放する手段を提供するというのは
|難しいでしょうか.
|もちろん自動でというのは効率上も無理でしょうから,
|スクリプトからの手動の要求によってという話です.
|
|「一時的なりともそれだけを必要とするんだから仕方がない」というのも
|事実だとは思いますが,長期間稼働するアプリケーションで
|一時的に作業に多量のメモリを必要とするというケースを考えると
|メモリ解放手段が用意されていると嬉しいと思うのですが.

えーと、おそらくはご存じだと思うのですが、Cには方法でOSにメ
モリを返す移植性のある方法がありません。UNIXならbrkを使えば
返せないことはないですが(でもbrkはPOSIXにない)、mallocが管理
している領域には手が出せません。

ということで、これをなんとかする方法は私には思いつかないので
す。使われているオブジェクトが全部回収されたヒープをfree()す
るくらいならできそうには思うのですが。これもプロセスサイズを
小さくするとは限りませんよね。

                                まつもと ゆきひろ /:|)

Attachments (1)

tk.patch (2.78 KB, text/x-diff)
--- tk.rb	2002/09/12 06:27:15	1.34
+++ tk.rb	2002/10/02 04:49:07
@@ -266,3 +266,3 @@
     id = $1 if /rb_out (c\d+)/ =~ id
-    Tk_CMDTBL[id] = nil
+    Tk_CMDTBL.delete(id)
   end
@@ -284,3 +284,3 @@
   def uninstall_win()
-    Tk_WINDOWS[@path] = nil
+    Tk_WINDOWS.delete(@path)
   end
@@ -2190,3 +2190,3 @@
         SAFE_MODE  = #{safe}
-        %w(#{func_str}).each{|f| METHOD_TBL[f.intern] = nil }
+        %w(#{func_str}).each{|f| METHOD_TBL.delete(f.intern) }
       end
--- tkafter.rb	2002/06/04 07:03:33	1.5
+++ tkafter.rb	2002/10/02 04:49:07
@@ -66,3 +66,3 @@
     if @running == false || @proc_max == 0 || @do_loop == 0
-      Tk_CBTBL[@id] = nil ;# for GC
+      Tk_CBTBL.delete(@id) ;# for GC
       @running = false
@@ -74,3 +74,3 @@
       else
-	Tk_CBTBL[@id] = nil ;# for GC
+	Tk_CBTBL.delete(@id) ;# for GC
 	@running = false
@@ -274,3 +274,3 @@
     @after_id = nil
-    Tk_CBTBL[@id] = nil ;# for GC
+    Tk_CBTBL.delete(@id) ;# for GC
     self
--- tkcanvas.rb	2002/06/28 14:40:25	1.15
+++ tkcanvas.rb	2002/10/02 04:49:07
@@ -506,3 +506,3 @@
     @c.delete @id
-    CTagID_TBL[@cpath][@id] = nil if CTagID_TBL[@cpath]
+    CTagID_TBL[@cpath].delete(@id) if CTagID_TBL[@cpath]
   end
@@ -690,3 +690,3 @@
     @c.delete @id
-    CItemID_TBL[@path][@id] = nil if CItemID_TBL[@path]
+    CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path]
   end
@@ -765,3 +765,3 @@
   def delete
-    Tk_IMGTBL[@id] = nil if @id
+    Tk_IMGTBL.delete(@id) if @id
     tk_call('image', 'delete', @path)
--- tkfont.rb	2002/06/04 07:03:33	1.11
+++ tkfont.rb	2002/10/02 04:49:07
@@ -566,3 +566,3 @@
   def delete_core_tk4x
-    Tk_FontNameTBL[@id] = nil
+    Tk_FontNameTBL.delete(@id)
     Tk_FontUseTBL.delete_if{|key,value| value == self}
@@ -583,3 +583,3 @@
     end
-    Tk_FontNameTBL[@id] = nil
+    Tk_FontNameTBL.delete(@id)
     Tk_FontUseTBL.delete_if{|key,value| value == self}
@@ -612,3 +612,3 @@
 	rescue
-	  Tk_FontUseTBL[w] = nil
+	  Tk_FontUseTBL.delete(w)
 	end
@@ -646,3 +646,3 @@
 	rescue
-	  Tk_FontUseTBL[w] = nil
+	  Tk_FontUseTBL.delete(w)
 	end
--- tktext.rb	2002/06/28 14:40:25	1.20
+++ tktext.rb	2002/10/02 04:49:07
@@ -687,3 +687,3 @@
     tk_call @t.path, 'tag', 'delete', @id
-    TTagID_TBL[@tpath][@id] = nil if CTagID_TBL[@tpath]
+    TTagID_TBL[@tpath].delete(@id) if CTagID_TBL[@tpath]
   end
--- tkvirtevent.rb	2001/05/06 15:04:27	1.4
+++ tkvirtevent.rb	2002/10/02 04:49:07
@@ -56,3 +56,3 @@
       tk_call('event', 'delete', "<#{@id}>")
-      TkVirtualEventTBL[@id] = nil
+      TkVirtualEventTBL.delete(@id)
     else
@@ -60,3 +60,3 @@
 	      *(sequences.collect{|seq| "<#{tk_event_sequence(seq)}>"}) )
-      TkVirtualEventTBL[@id] = nil if info == []
+      TkVirtualEventTBL.delete(@id) if info == []
     end

In This Thread