トップページtech
582コメント172KB

プログラミング言語 Lua

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
Lua について語ろう。

http://www.lua.org/
0256デフォルトの名無しさんNGNG
 うーん、なんかLuaのメモリ管理ってガベコレしてるのか知らんけど、
すんげー量の未使用メモリが残るのな。開放のタイミングも全然良く解か
らんし、こりゃメモリリソースがキツい環境じゃ使用がためらわれるな。
断片化怖いしな。
0257デフォルトの名無しさんNGNG
でも、その割にはゲームとか組み込みとかリソースの厳しいアプリが多い様な
0258デフォルトの名無しさんNGNG
>>256
そりゃダメダメだな。
採用しようかと思ってたが、見送ることにするよ。
0259デフォルトの名無しさんNGNG
コメントは、漏れも#に変えて(ソース変えて)使ってる。
ただ、MLの感じでは5.1あたりから#もコメントとして認識される方向のようだね。
0260デフォルトの名無しさんNGNG
Cプログラムからのアクセスの仕方がよくわからないです。
わかりやすく説明してほしいなぁ。
0261デフォルトの名無しさんNGNG
どのへんが分からんの?
0262デフォルトの名無しさんNGNG
>>261

>>248の例だと、
co = lua_newthread(L); ここで"test.lua"の実行環境整えて、
lua_getglobal(co, "co_func"); co_funcを探して、
lua_pushnumber(co, i); co_funcに引数わたして、
printf("c: resume=%d\n", lua_resume(co, 1)); co_funcがyieldを実行するまで待って、
printf("c: co result1=%lf\n", lua_tonumber(co, -2)); スタックから結果を取り出す。
って感じで理解できるんだけど、

>>246の例では、getglobalとかgettable,settop等が何をやっているのかわかりません。
0263262NGNG
あと、
>>248の例で、co_funcがどのタイミングで実行されるのかもわかりません。
0264デフォルトの名無しさんNGNG
>>262
あー、coroutine, thread関係はとりあえず忘れたほうがいいかも?
5.0の新機能だし。

>>246のforの前まではLuaで書くと、以下の文と同様のことをしてる。

 co = coroutine.create(co_func)

(1)lua_getglobal(L, "coroutine");
 グローバル変数"coroutine"をスタックのトップに積む
 ちなみにこいつはテーブルだ。

(2)lua_pushstring(L, "create");
 文字列"create"をスタックのトップに積む

(3)lua_gettable(L, -2);
 スタックのトップから2番目の要素((1)のcoroutineのこと。テーブルである必要がある。)から、
 スタックのトップに積んである文字列("create")で示されるメンバをスタックに積む。
 このとき、スタックのトップはpopされる。
 ちなみに、createメンバは関数なので、その関数がスタックのトップに詰まれる。
 こいつは、(4)で使われる。

(3)lua_getglobal(L, "co_func");
 test.luaで定義された関数co_funcをスタックのトップに積む。

続く...
0265続きNGNG
(4)lua_call(L, 1, 1);
 関数コール: 引数が(3)のco_funcで、呼ぶ関数が(2)のcreate。
 ちなみに、lua_call(L, m, n)と呼ぶときは、スタックは以下のようになってなければならない。
  stack: ... [関数] [引数1] [引数2] ... [引数n] <- ここがスタックのトップ
 で、呼ばれるとスタックはこうなってる↓。
  stack: ... [戻り値1] [戻り値2] ... [戻り値m] <- ここがスタックのトップ
 つまり、(4)は、
  [関数"create"] [関数:"co_func"] -> [createの戻り値(スレッド)]
 となるわけだ。

(5) co = lua_tothread(L, -1);
  lua_setglobal(L, "co");
 スタックのトップから値をスレッド型でとってきてそれをグローバル変数"co"に設定する。

こんなんで分かるかな?スタックの状態を想像しながら読んでくれ。
coroutineのことは置いといて、LuaをCから使うための基本は大体入ってるような
気がする(グローバル変数の操作、テーブルの操作、Luaの関数呼び出し)。 
あとは、indexの指定の仕方とかどの関数で何がpushされて何がpopされるかが
分かれば大体作れると思うんだけど。

ちなみにcoroutineは、lua_baselibopen(L)を呼んだときに定義されます(ハズ)。
0266デフォルトの名無しさんNGNG
あ、ごめん。nとmが逆だ。
× ちなみに、lua_call(L, m, n)と呼ぶときは、スタックは以下のようになってなければならない。
○ ちなみに、lua_call(L, n, m)と呼ぶときは、スタックは以下のようになってなければならない。
0267デフォルトの名無しさんNGNG
>>263
関数が呼ばれるのは、lua_resumeが呼ばれたとき。
lua_resumeは、スレッドのスタックの一番下(index=1)に積んである関数を
呼ぶ(もしくはyieldで中断された実行を再開する)関数ね(多分)。
lua_resumeに指定するのはLじゃなくてスレッドオブジェクトだということに注意。

で、>>248>>246
co = coroutine.create(co_func)
for i = 0, 3 do
  r1, r2 = coroutine.resume(co, i)
  print("main:", r1)
  print("main:", r2)
end
と動作的には同じ事をしてる(厳密に同じわけじゃないけど)。
test.luaのこいつを書き加えれば同じように動くよ。
0268デフォルトの名無しさんNGNG
C の continue 相当ってどう書いてる?
0269デフォルトの名無しさんNGNG
>>264-267
coroutine.createってcoroutine["create"]って感じですね。
すごくわかりやすくて、Luaを組み込めるようになりそうです。
どうもありがとうございます。
0270デフォルトの名無しさんNGNG
マニュアルの日本語訳ってどこ行っちゃったの?
http://216.239.53.100/search?q=cache:www.etl.go.jp/etl/divisions/~ueno/lua/manual4jp.html
0271デフォルトの名無しさんNGNG
こっちに移ったみたい
http://staff.aist.go.jp/yutaka.ueno/lua/manual4jp.html
0272デフォルトの名無しさんNGNG
おお!サンクス。
こっちは最後まであるんだね。
これまで、googleのキャッシュをローカルに保存してみてたので、
ちゃんとしたのがあるのは嬉しいなぁ。
0273デフォルトの名無しさんNGNG
そういえば、Lua4.0とLua5.0bのC言語APIは微妙に違うんだよね。
ちょっとだけ混乱したよ。
0274デフォルトの名無しさんNGNG
table.function(a, b, c)

table:function(a, b, c)
は逆にして欲しかった。
もしくは、JavaScriptみたいにselfを暗黙のローカル変数にするか。
0275デフォルトの名無しさんNGNG
変えたいなら、さっさと修正すりゃいいじゃん。
0276デフォルトの名無しさんNGNG
仕様といえば、複数値がかえせるのに
それを一挙に代入しようとすると、扱いが変わってしまうとき
があるようなので、ちょっと萎えた。
0277デフォルトの名無しさんNGNG
そうなんだっけ?
例えばどんな場合か書いてもらえると嬉しい。
0278デフォルトの名無しさんNGNG
たとえば、
x,y=2,3
ならお望み通り

しかし、aho(0)->4,5 と返す関数があったとして、
x,y,z=aho(0),6
としてみて!
0279デフォルトの名無しさんNGNG
>>278
たとえば
A, B, C を集合とするとき <a,b>∈A×B, c∈C に対して
<x,y,z> = <<a,b>, c> で x=a ∧ y=b ∧ z=c を期待すべきか?
まあ、確かにそうかも知れない。

しかし、
x,y,z = 1,2 ; x == 1 and y == 2 and z == nil
が成り立つ世界でもそれは妥当か?
0280デフォルトの名無しさんNGNG
で、
function a()
  return 1, 2
end
x, y, z = 0, a()
とすると、
x=0, y=1, z=2
なんだよね。

確かに一貫性がないように見えるね。
リスト中に多値を返す関数がある場合は、
・リストが展開される
・常に戻り値が一つに丸められる
のどちらかに統一した方が仕様的には美しいかも?まぁ、好みの問題か。
(ただ、前者だと関数がいくつ値を返すかによってプログラムの動作が
異なってしまうので好ましくない。)

ちなみにこの辺の動作は、マニュアルの「Calling Functions」の項に
それとなく書かれてる。
0281280NGNG
うそ。
×「Calling Functions」の項
○「Function Calls」の項
http://staff.aist.go.jp/yutaka.ueno/lua/manual4jp.html#SECTION00045800000000000000
0282デフォルトの名無しさんNGNG
print((function()end)()) と a=(function()end)(); print(a) が違うのは気持ち悪い
0283280NGNG
>>282
ん?自然だと思うが?
0284デフォルトの名無しさんNGNG
>>282
L
ua 4.0 Copyright (C) 1994-2000 TeCGraf, PUC-Rio
>
> print((function()end)())
error: `)' expected;
last token read: `(' at line 1 in string "print((function()end)()) "
>
なんか実行できねーんですけど。
このインタプリタなんかおかしい?
0285デフォルトの名無しさんNGNG
> a=(function()end)(); print(a)
error: <statement> expected;
last token read: `(' at line 1 in string "a=(function()end)(); print(a) "

なんなの、これ。
一つも実行できねえ。
全然駄目だ・・
0286デフォルトの名無しさんNGNG
つーかエラーの意味がさっぱりわかんねえ。
これでどうしろと。
0287デフォルトの名無しさんNGNG
$ lua -v
Lua 5.0 (beta) Copyright (C) 1994-2002 Tecgraf, PUC-Rio
$ lua -e 'print((function()end)())'

$ lua -e 'a=(function()end)(); print(a)'
nil
0288デフォルトの名無しさんNGNG
>287
-eつかわないでやりたいんだけど
0289デフォルトの名無しさんNGNG
つーか5.0ってベータじゃん。そんなの使いたくねえ
0290デフォルトの名無しさんNGNG
>>289
んじゃこれ

$ lua4
Lua 4.0.1 Copyright (C) 1994-2000 TeCGraf, PUC-Rio
> function f() end
> print(f())

> a=f(); print(a)
nil
0291デフォルトの名無しさんNGNG
>290
そっちは通った。
なんで>>282はダメなの?
なんかLuaって構文的に変だよな。
0292デフォルトの名無しさんNGNG
>>291
ただ単に、
'(' 式 ')' '(' 引数リスト ')'
っていう構文が定義されてないだけでしょ。

5.0にあるHISTORYに
+ more general syntax for function calls (e.g. (print or write)(9)).
とか書いてあるから、>>282みたいな構文は5.0から新設されたんだと思われ。
0293デフォルトの名無しさんNGNG
>>291
4のころは
function foo() return function() end end
とは書けたけど、無名関数に適用する構文がなかった。
関数がファーストクラスオブジェクトな言語ではそれは不便なわけで、
実際5では使えるようになったわけで、喜ばしいんじゃないの。
0294デフォルトの名無しさんNGNG
>>282 は多値と値の個数の関係が気になったんでやってみた。
function f0() return end
function f2() return 1,2 end
に対して
a,b,c,d = f2(),f0(),f2(),f0() は a,b,c,d=1,2,1,2 か a,b,c,d = 1,2,nil,1,2 か。
しかし実際はどちらでもなく a,b,c,d = 1,nil,1,nil となる(>>278)。
では print(f2(),f0(),f2(),f0()) はどうか。
これは print(1,nil,1) と等価(省略可能な引数は値がなければ渡されないから)。
まあ仕組みは分かるんだけど、理屈は納得しにくい。
0295デフォルトの名無しさんNGNG
そんなことよりendがうざいんですけど。
英語メール打ってよ。
「日本ではendが不評です。
functionは長すぎです。」って。

あとさ、returnあるときと無いときってどうなってるの?
print(function()end)
ってreturn書いてないからエラーにすべきじゃないの?

a = function()end
print(a())

print(a(), 1)
nil 1
結果も違うし、おかしいよこれ。
0296デフォルトの名無しさんNGNG
print(a(),a())
nil
さっぱりわからん
0297デフォルトの名無しさんNGNG
>>295
値のない関数自体は悪くないんじゃない?
まあ明示的な return がなければ最後の値またはnilを返すというのもありだと思うが。
それから>>294もいってるように最後の引数は省略可能なので
print((function()end)()) は print() と同様の扱い。
0298デフォルトの名無しさんNGNG
もう一から設計し直した方がいい気がする・・・。
0299デフォルトの名無しさんNGNG
> function argn(...) print(arg.n) end
> function nul() end
> argn(nul())
0
> argn(nul(),nul())
1
> argn(nul(),nul(),nul())
2
0300デフォルトの名無しさんNGNG
>>297
そういうことじゃなくて、つまりさあ、
a()は値を返さない関数なわけだから、
他の関数の引数として使われた時点でエラーにでもしないと
辻褄合わないでしょって事。これじゃバグ埋めこみまくり。

print(a())
error: 値を返さない関数a()を引数に適用しました

とかなんとか。
もうだめぽ。
0301デフォルトの名無しさんNGNG
まー、確かに関数呼び出しの戻り値の評価のされ方が文脈依存ってのは、
ちょっと気持ち悪いかもな。
C言語APIいじってるとそのうち違和感なくなったりするんだがw
0302デフォルトの名無しさんNGNG
> a
error: `=' expected;
last token read: `<eof>' at line 1 in string "a"

もういいや。
疲れただけだった。
0303デフォルトの名無しさんNGNG
こんな感じで処理されてるんよ。多分。

・リスト(引数リスト、多値代入リスト)の途中に現れた場合、1個の戻り値が要求される
・リストの最後に現れた場合、戻り値がそのままリストに加えられる
・どちらの場合でも、戻り値が要求された個数に満たない場合はnilが補完される。
 また、多すぎる場合、先頭から要求された個数のみ使用される。
5.0からは次の場合が追加されてる。
・()で括られた場合、1個の戻り値が要求される。

んで、要求された個数だけ値がリストに加えられて、多値代入なり、
関数コールに使われるわけだね。
0304デフォルトの名無しさんNGNG
>>300
うーむ、どういうバグを埋め込んでしまうんだろう。。。?
0305デフォルトの名無しさんNGNG
>>304
値を返すつもりがreturn書いて無かった

エラー出ない

気付かない

動かない
0306デフォルトの名無しさんNGNG

Lua使えねえ

作者にスパムメール

タイーホ

(´・ω・`) ショボーン

仮釈放

復讐のオニ(`・ω・´)

作者にスパムメール

(繰り返し)
0307デフォルトの名無しさんNGNG
>>305
動的型付けの言語でそれを期待する方がおかしいと思うが…。
luaだけの問題じゃないし。
(というか、インタプリタでそういうえら出すやつってあんまりないような。)
0308デフォルトの名無しさんNGNG
っと、動的型付けはあんまり関係ないか。
0309デフォルトの名無しさんNGNG
>>307
ちゃんと読んでよ。
問題はそこじゃないくて、returnの付け忘れで値が変化することだろ。
防止できないならreturnなんて構文は無い方がいい。
ということ。
0310デフォルトの名無しさんNGNG
LISPとかRubyは全ての構文が値を返すという前提があるから
こういう問題は起きない。
0311デフォルトの名無しさんNGNG
ああ、なるほど。
>>298に同意。
0312デフォルトの名無しさんNGNG
RubyだってLISPだって「値を返すための処理」を付け忘れたら同じことになるんじゃない?

それともそのバグのある関数をほかの関数呼び出しの引数の最後にくっつけたとき、
渡される引数の個数が異なるのことを問題にしてる?
0313デフォルトの名無しさんNGNG
>>312
>>309
0314デフォルトの名無しさんNGNG
結局何が言いたいのかよく分からん

rubyなら、
def foo
 initialize()
 result = ...
finalize()
result
end
def foo
 initialize()
 result = ...
finalize()
end
で、値が違ってくるでしょ?
これは、luaのreturnありなしと同じことじゃない?
それともこんな書き方は「できない」ようにした方がいい?
0315デフォルトの名無しさんNGNG
>>312 >>314
つまりこういうこと。

> a = function() return 0 end
> b = function () a() end --return付け忘れた
> b()
> print(a())
0
> print(b())


あれれ・・
0316デフォルトの名無しさんNGNG
やっぱ設計し直した方がいいよこれ
0317デフォルトの名無しさんNGNG
>>315
やっぱり引数の数を問題にしてる?
それが問題になるのは、可変長引数の関数のときだけでしょ?

もしくは、本当に値のことなら、
def foo
 0
end
def foo
 0
 print "debug..."
end
とか、つまらんミスだけど完全には「防止」できないよね?
(俺には「値を返す場所が1つ」で「そこにreturnを付け忘れた」なんていうミスは
上と同列(文法を理解してない)に見える。)

まぁ、関数にreturnが一つでもついていたら、
「returnで値を返さないパスが存在します。」とかの
warningくらい出してくれてもバチは当たらないだろうけどね。
0318デフォルトの名無しさんNGNG
>>317
なんか、全然理解してくれてないね。
もういいよ。
0319デフォルトの名無しさんNGNG
ふうむ、もし return を無意味にするためにすべての構文が値を持つようにしたら、
代入文も値を持つので a = b = 0 とか出来るようになるが、
一方で a = b == 0 も合法になるので、
if a = 0 then ... end というありがちな罠が出来るわけだがその辺はどうよ。
0320デフォルトの名無しさんNGNG
うぅ。ほんとに理解できないんだよ。俺が馬鹿なのか?
誰かもっと実際にありえそうな例で解説してくれ。
0321デフォルトの名無しさんNGNG
>>320
あんたの好きなrubyの場合、
def a(x) print(x) end と def a(x) return print(x) end で a(1) は nil を返すし、
lispならそもそも return がないが、lua の場合、
function a(x) print(x) end と function a(x) return print(x) end は違うのが危ない
っていってんだろ。
0322デフォルトの名無しさんNGNG
> a = function(x) if x == 0 then return 0 else b() end end
> b = function()end
> print(a(b()))

> print(a(0))
0

確かに危険だなこれ。
0323デフォルトの名無しさんNGNG
PascalやVBで言う、「手続き」と「関数」がいっしょくたに書けてしまう
という事だな。
Luaは関数のくせに値を返さない可能性がある。
0324デフォルトの名無しさんNGNG
function やめて subroutine にすれば解決
0325デフォルトの名無しさんNGNG
>>324
その場合もfunctionで書いたとき、
return忘れをチェックできないと解決しない。
全ての関数が値を返すという前提で、
return削除するのが一番簡単で楽だと思うけど。
0326デフォルトの名無しさんNGNG
5.0とかバージョン番号は立派だが、まだ使える段階の言語じゃないな。
0.5の方がいいんじゃないのか。
0327デフォルトの名無しさんNGNG
>>325
returnはセミコロン(;)と同じ様に、あってもなくてもいい事にすれば、
修正も最小限で済むかな。
さらに変な言語になるけど。
0328デフォルトの名無しさんNGNG
>>325
いやいや、subroutine は本来値を持つものではないのよ。
しかし return によって値つきで戻ることが出来るわけで。
0329デフォルトの名無しさんNGNG
リターンなかったらnilを返すようにすればいい。
0330デフォルトの名無しさんNGNG
そもそも値を返さない function を用意したのはなぜなんだろ
単に構文要素 procedure をケチっただけなんだろうか
0331デフォルトの名無しさんNGNG
>>328
なんじゃそりゃ。

>>329
それも問題ある。
というか問題が変わってない。
0332デフォルトの名無しさんNGNG
作ったやつに大きな欠陥があるな。これは。
付き合いきれん。
0333デフォルトの名無しさんNGNG
 なんかウゼーやつが粘着してんな。ruby厨はどこ行ってもこうだよな。
気に入らないなら使わなきゃいい。これだけヌルいライセンスなんだから
解決策も上げずにクダクダ文句言うのはお門違いだ。キエロ
0334デフォルトの名無しさんNGNG
ruby厨逝ってよしには同意だが見てる限りじゃ文句いってるのはruby厨ではなさそう
0335デフォルトの名無しさんNGNG
・functionとprocedureを分ける。
・functionで、returnがない実行パスがあった場合エラー
・procedureは引数リストや代入の中で使えない
でOK?

parserの改造くらいですみそうだが。
0336デフォルトの名無しさんNGNG
>>333
解決策は上がってるじゃん。
つーかウザそうなやつって、真っ先にお前じゃねーか(w
0337デフォルトの名無しさんNGNG
そだな。よく読むとただのガイキチのようだ。スマヌ>ruby厨

 ところで、ちょっと前にも話題に出したのだけどlmem.c内のメモリ
確保/開放の所をトレースすると全くと言って良いほど開放が行われて
いないのね。試しにループコード書いてみたらメモリが100M近くまで
確保されても開放する気配もなかった。っていうか通常でも良く解か
らないタイミングでメモリ確保するのね。たとえば
a=1
これだけの行でも数個のメモリを確保してる。(しかも開放しやがらねー)

 生成したスレッドの開放手段も用意されてないし、クラスモドキは
作れてもデストラクタが作れないとか、いろいろと組み込みには問題が
山積みのような気がする。

 betaだからだと思いたいなぁ。
0338デフォルトの名無しさんNGNG
Luaの中の人も変だったな。
0339デフォルトの名無しさんNGNG
>>337
gc積んでるんじゃないの?
0340デフォルトの名無しさんNGNG
>>335
互換性考えるなら、>>325 and >>327
0341デフォルトの名無しさんNGNG
>>339
そそ、GC積んでるみたいなんだけど、開放タイミングが良く解からないのね。
っていうか、メモリ周りはもうちょっとクリーンに使えないとつらいねぇって話。
出来る事ならメモリ周りはlua_openの時のみ1回の確保にして貰えると助かる。
足りないときは例外投げて再確保とかがいいな。
0342デフォルトの名無しさんNGNG
>>337
というかそもそもl_free()ってreallocでしか使われてないじゃん。

GCの後余ったメモリをOSに返すようにするGCって稀なんじゃないかな。
コンパクションのときオブジェクト再配置でかかるコストとか馬鹿にならなそう出し。
んで、確保したメモリは1回メモリプールに置いといて、足らなくなりそうだったら
改めて確保するわけだ。だからタイミングが不定に思えるんでしょう。

前にメモリの断片化を心配してたみたいだけど、オブジェクトサイズは
ほぼ一定の大きさになるようにして、文字列とか不定長のやつは別管理にする
とかいうメモリ管理をするのが一般的だと思う、インタプリタでは。
(luaがどうなってるのかは知らないが。realloc()のコストが高そうだ…。)

まぁ、組み込み用途としては失格なのかもしれんが(組み込み機器なんかで使いたい場合は特に。)

デストラクタは、自分で作って明示的に呼びましょうってことじゃない?
Javaと同じく(Javaには一応あるけど事実上使えないよね)。
0343342NGNG
ソース見てみたけど、たしかにluaのメモリ管理はちょっとアレだね。
どかっとメモリ確保してそれを分割して使うわけじゃないのか。
ちなみに、4.0もほぼ同じコードなのでbetaとれても変わらないでしょう。

まぁ、lmem.cのreallocを自分で固定メモリ領域から取ってくるように
改造すれば対応可能だから、まだましか…?
そういうのを作ってコントリビュートしてみてもいいかもね。
0344デフォルトの名無しさんNGNG
>>343
うん。lmem.cを見る限りでは外部のallocaterを利用する事も考慮している
みたいなんよね。ただ、開放のタイミングがちょっとアレなので例えばメモ
リプールを64kとかするとあっという間に溢れちゃう。やっぱメモリは不要に
なった先から開放して欲しいっす。
 ここをなんとかしないととてもじゃないけど組み込みどころかPCでも使え
ないすね。っていうかどうゆう環境を想定してんだろ…。

 個人的にはメモリブロックを取得して保存/復帰が出来るようになれば
サイコーなんだけど…。
0345デフォルトの名無しさんNGNG
 あぁ、ごめん、ちょっと迂闊な事書いたかも。GCのしきい値を決める
void lua_setgcthreshold (lua_State *L, int newthreshold);
って関数があるね。

 ちとLuaをガベコレレスに改造するテストしてみようと思います。上手
くいったらレポートします。

 あとはスレッドの開放だな…。
void lua_closethread (lua_State *L, lua_State *thread);
はマニュアルに記述はあるのでそのうちFixされると思いたいのだが…。
0346デフォルトの名無しさんNGNG
PCだと、有名どころで
・Baldur's Gate
・MDK2
・Angband
とかあるね。
まぁ、どこで使われてるか、ってのも問題だけど。
BGはAIのところだっけ?
0347デフォルトの名無しさんNGNG
>>279 4/10 8:50〜の1日だけで投稿数68か。何かあったのかな?
荒らしでもなく、sage優先にしては記録的!
でも、ageると嵐が来そうなので、sageておこうっと。
0348デフォルトの名無しさんNGNG
>>347
Luaの仕様をちゃんと理解できないやつが難癖つけてただけじゃない?
0349デフォルトの名無しさんNGNG
>>337
free()で領域がOSに返るかどうかはlibc依存なんだがそういう話ではない?
現状ではOSに返らない環境の方が多いと思う。
0350デフォルトの名無しさんNGNG
>>349
そういう話ではない。
0351デフォルトの名無しさんNGNG
どういう話なんだかよくわからないな。

メモリが足りなくなった時に追加確保しないでゴミ掃除なりして欲しいってこと?
(ちゃんとソース読んでないけど) safe-point 方式っぽいからしょうがないんじゃないのかなあ。

参照カウント方式はカンベンしてほしいし。
0352デフォルトの名無しさんNGNG
>>337
top(1)で観察できるluaのコードは何かありますか?
0353デフォルトの名無しさんNGNG
GCは単純なマーク&スィープ方式だね。
こいつは、オブジェクトが多くなればなるほど時間がかかるという弱点を持ってる。

上の話は、言語で一括してメモリプールを取るんじゃなくて
オブジェクトを作るたびにmalloc()が走るからメモリ使用状況が
把握しにくいから嫌、って話じゃない?
んで、解決方法としては、malloc()のソースとか持ってくるなりして
アロケータを適当に書く、と。

実際には、言語内で確保したオブジェクトをプールしてるのか、
しばらくするとアロケータもGCもあんまり走らなくなるんだけどね。
(複雑なサンプルでは試してないけど、単純ループとか再帰とかでは。)
0354デフォルトの名無しさんNGNG
>>353
 コード追ってみました。ほぼ353氏のいうとおりですね。不思議なのは
最後にあるようにある程度走らせたらメモリの再利用らしき挙動が起こっ
てメモリの確保が行われなくなる事かな。ガベコレってそういうもんなの
かも知れないけど、これがちょっと困り者。

 ぶっちゃけ、自分が想定していた家庭用ゲームコンソールへの組み込み
はよほど扱いを限定しないとむつかしそうな感じです。PCゲーならOKかな?
0355デフォルトの名無しさんNGNG
えらい伸びようだなぁ〜
なんかGCにいちゃもんつけてる粘着がいるみたいだけど、
第一そんなにシビアな環境でなんでインタプリタ使うんだ??
俺には信じられんが。。。(w

まぁ、PCゲーあたりが現実的なターゲットかと。。
0356デフォルトの名無しさんNGNG
>>355
LuaのWikiでは、ゲームに使うためにGCを何とかしようとかいう議論もあったけどね。
インクリメンタルGCとか世代別GCとか。
俺的には、リアルタイム性という点では、mark&sweepより参照カウントのほうが
向いてると思うんだけどね。Luaを参照カウント方式にするのはかなり労力掛かると思うが…
で、保険としてmark&sweepも入れておくと。

全体的にLuaはメモリアロケーションが少なくてすむように設計されてるように見えるので、
メモリ管理関係にあんまりこだわるのも本質じゃないのかも(もう少しソース追わんと
はっきりとしたこといえないけど。)
ただ、Luaのソース上でのGC呼び出しタイミングとか見てみると、どうもmalloc()が失敗する
ことはほぼ無いという前提で作ってるように見えるので、組み込み系はちょっときついのも
確かか。
■ このスレッドは過去ログ倉庫に格納されています