[ 新規に投稿する ]

サブルーチンのローカル変数と引数の終了後の解放についてNo.09853
fzok4234 さん 22/04/20 23:12 [ コメントを投稿する ]
  毎度お世話になっております。


さて、マクロ変数用のメモリ領域について少し分からないことがあります。call 文で呼び出す
サブルーチンの中の、
 $$string
 ##numeric
とかのローカル変数や、
 ##1
 $$2
とかの引数に割り当てられたメモリ領域は、サブルーチンを return ; で終了させたら速やかに
解放されるのでしょうか ?

変数用メモリ領域の上限が最大で 64MB と手狭な中で、もしローカル変数と引数に割り当てられた
メモリがマクロ全体の終了まで居座り続ければ、大量のサブルーチンの使用の際にメモリリークが
発生してしまい、メインのグローバル変数の容量がどんなに少なくても変数用メモリが枯渇して
しまいます。

例えば、文末に掲示したような極端なケースの場合、もしメモリリークがあればあっという間に
メモリ不足のエラーとなってしまいます。

現実には、1 つのマクロにサブルーチンを万単位で作ることはまずありません。しかし実際の運用では、
同じシグネチャで中身の異なるサブルーチンの「配列」を数十 〜 数百個単位で用意して、その
サブルーチンの名前文字列値を「関数ポインター」のように扱って状況に応じて呼び出すサブルーチンを
切り替える、ということはよくあります。

今のところ、万単位でサブルーチンを書く作業が大変なため、当方でテストはまだ行っていません。
また、当方で実際に使用しているマクロでもメモリ不足のエラーにはまだ出くわしていません。

しかし、サブルーチンの終了でのメモリ開放が正しく実装されているのか、それともメモリリークが
本当に存在しているのか当方で把握し切れていないため、今後マクロに新しいサブルーチンを追加しただけで
メモリ不足のエラーが起きないかどうか不安なところでございます。

ローカル変数と引数のメモリ管理に関する詳細な説明を、どうかよろしくお願い申し上げます。


debuginfo 2 ;

#index = 0 ;
while ( #index < 65536 ) {
    $delegate = @"Function_" + str( #index ) ;
    call $delegate
            #index
        ,       @"寿限無寿限無五劫の擦り切れ海砂利水魚の水行末雲来末風来末食う寝る処に住む処"
            +   @"藪ら柑子の藪柑子パイポパイポパイポのシューリンガンシューリンガンのグーリンダイ"
            +   @"グーリンダイのポンポコピーのポンポコナの長久命の長助"
    ;
    
    #index = #index + 1 ;
}

endmacro ;

Function_0
    $$value = str( ##1 ) + @" : " + $$2 ;
    debuginfo $$value + "\U0000000A" ;
    return $$value ;

Function_1
    $$value = str( ##1 ) + @" : " + $$2 ;
    debuginfo $$value + "\U0000000A" ;
    return $$value ;

Function_2
    $$value = str( ##1 ) + @" : " + $$2 ;
    debuginfo $$value + "\U0000000A" ;
    return $$value ;

// .... 以下繰り返し。....

Function_65534
    $$value = str( ##1 ) + @" : " + $$2 ;
    debuginfo $$value + "\U0000000A" ;
    return $$value ;

Function_65535
    $$value = str( ##1 ) + @" : " + $$2 ;
    debuginfo $$value + "\U0000000A" ;
    return $$value ;


[ ]
RE:09853 サブルーチンのローカル変数と引数の終了後の解放にNo.09854
こみやんま さん 22/04/21 00:45 [ コメントを投稿する ]
  call してreturnした後、ローカル変数は消える(解放)されるものの、別のユーザー関数をcallしない限り、$$result の分がずっとマクロ終了までは残るので、
メモリ残量は予期しにくいでしょうね。

-----------------------------------------------------------------------
$a = R"RAW(
飛騨プラネタリウムは、岐阜県高山市にあるプラネタリウムである。高山市の条例上の名称は高山市飛騨プラネタリウムである。飛騨地域唯一のプラネタリウムであり、科学および科学技術に関する知識の普及および啓発を図ることを目的とした施設である。……
遠州&#24553;劇とは、永禄5年(1562年)から同9年(1566年)にかけて発生した、遠江国内の主に天竜川流域における複数の国衆による駿河今川氏への大規模な叛乱のことである。戦国期の遠江国は駿河今川氏の侵攻を受け、永正14年(1517年)に今川氏親が遠江守護である斯波氏を打ち破り、……
流星クラスター現象は、発見者の名前から木下現象とも呼ばれ、短時間に多数の流星が集中的に流れる現象である。1997年に、しし座流星群の観測を行っていた日本流星研究会の木下正雄らが初め
飛騨プラネタリウムは、岐阜県高山市にあるプラネタリウムである。高山市の条例上の名称は高山市飛騨プラネタリウムである。飛騨地域唯一のプラネタリウムであり、科学および科学技術に関する知識の普及および啓発を図ることを目的とした施設である。……
遠州&#24553;劇とは、永禄5年(1562年)から同9年(1566年)にかけて発生した、遠江国内の主に天竜川流域における複数の国衆による駿河今川氏への大規模な叛乱のことである。戦国期の遠江国は駿河今川氏の侵攻を受け、永正14年(1517年)に今川氏親が遠江守護である斯波氏を打ち破り、……
流星クラスター現象は、発見者の名前から木下現象とも呼ばれ、短時間に多数の流星が集中的に流れる現象である。1997年に、しし座流星群の観測を行っていた日本流星研究会の木下正雄らが初め
飛騨プラネタリウムは、岐阜県高山市にあるプラネタリウムである。高山市の条例上の名称は高山市飛騨プラネタリウムである。飛騨地域唯一のプラネタリウムであり、科学および科学技術に関する知識の普及および啓発を図ることを目的とした施設である。……
遠州&#24553;劇とは、永禄5年(1562年)から同9年(1566年)にかけて発生した、遠江国内の主に天竜川流域における複数の国衆による駿河今川氏への大規模な叛乱のことである。戦国期の遠江国は駿河今川氏の侵攻を受け、永正14年(1517年)に今川氏親が遠江守護である斯波氏を打ち破り、……
流星クラスター現象は、発見者の名前から木下現象とも呼ばれ、短時間に多数の流星が集中的に流れる現象である。1997年に、しし座流星群の観測を行っていた日本流星研究会の木下正雄らが初め
飛騨プラネタリウムは、岐阜県高山市にあるプラネタリウムである。高山市の条例上の名称は高山市飛騨プラネタリウムである。飛騨地域唯一のプラネタリウムであり、科学および科学技術に関する知識の普及および啓発を図ることを目的とした)RAW";

$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;
$a = $a + $a ;

call Function_0 $a;
endmacro;

Function_0:
return $$1+$$1;

-----------------------------------------------------------------------

最後の$$1+$$1を、$$1 にするとメモリは溢れない。
[ ]
RE:09854 サブルーチンのローカル変数と引数の終了後の解放にNo.09855
fzok4234 さん 22/04/21 10:36 [ コメントを投稿する ]
  こみやんまさん、調査ありがとうございます。


一応、ローカル変数と引数はサブルーチン終了後にちゃんと破棄されるとのことで安心しました。


> $a = $a + $a ;
> $a = $a + $a ;
> $a = $a + $a ;
> ...

容量をわざと指数関数的に爆発させるために、このような方法があったのだと、目から鱗が落ちる
思いです。


[ ]
RE:09855 サブルーチンのローカル変数と引数の終了後の解放にNo.09857
秀丸担当 さん 22/04/21 18:24 [ コメントを投稿する ]
  私のほうからもコメントしておくと、サブルーチンをreturnして終わったら、ローカル変数は消去されることになっています。
[ ]

[ 新規に投稿する ]