[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2ch.scのread.cgiへ]
Update time : 02/26 16:42 / Filesize : 210 KB / Number-of Response : 738
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

GCは失敗。メモリは自分で管理せよ! その2



1 名前:デフォルトの名無しさん mailto:sageteoff [2015/11/18(水) 23:24:59.79 ID:BUQ68wTG.net]
GC、ガベージコレクション、ガベージコレクタ、ガーベジコレクション、ガーベジコレクタは使えない。
以下GCと記す

プログラマをメモリ管理から開放する!
といいつつ、メモリリーク問題の文献が大量にある。
これすなわち、メモリリーク問題が全然解決していないということ。
さらに、メモリ解放のタイミングの文献まで大量に生み出した。
これすなわち、新たなるメモリ管理に関する問題を生み出したということ。

malloc、freeじゃないが
結局のところ、メモリを管理するという技術は、今しばらくは、身につける・教える・学ぶべきではないだろうか?
使って、そのまま放置しても、基本的にはGCがなんとかしてくれている。
ランジョブからジョブ終了までさほどの時間を要さない。メモリも大して使わないならいいだろう。
しかし、規模が大きくなり常駐ジョブやメモリ大量使用のジョブになってくると、そんなメモリ管理の方法でやっていると、
上記「文献」を生み出されてしまう。

入門時は、メモリに無頓着でもいいだろう。それよりも、目的を達成することが先決だ。
しかし、慣れてきたら、やはりメモリの管理まで余裕を持って自分で行うべきだろう。

前スレ
GCは失敗。メモリは自分で管理せよ!
peace.2ch.net/test/read.cgi/tech/1412986420/

415 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 19:10:36.57 ID:nXtJgRqN.net]
>>405
SSOのが遅いだろ
>>406
size_t にしとけばオーバーフローしない

416 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 19:44:45.11 ID:R9brpoqy.net]
>>406
殿堂入りさせて、回収しない

417 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 20:22:44.37 ID:QL60ocAy.net]
>>407
確かに現実的にオーバーフローしないと言えると思うけど
STLとかもそういう実装になってる?

418 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 20:52:01.21 ID:rTAUpSul.net]
使う側は少なくとも1つのポインタを持たなくちゃいけないんだからオーバーフローし得ないだろ

419 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 22:10:23.58 ID:6zuFQelp.net]
マルチスレッドでGCスレッド立ち上げて、再配置起こる可能性のある普通のGCだと、オブジェクト毎にLock,Unlockできる何らかの機構が必要だし、参照カウンタ増減するより高頻度でその機構使うよね。

420 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 22:34:25.82 ID:2IjmMYr5.net]
そうでもない

421 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 23:56:59.65 ID:MgEq8J/o.net]
例えばWindowsだとInterlocked系のAPIを使えば
マルチスレッドでも安全に参照カウンタを増減できるから
パフォーマンスは何の問題もない

422 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 00:13:33.76 ID:MdJCnp0Y.net]
C#なら参照のコピーはただのワード代入で済む
メモリ確保もポインタへの加算だけで済むから圧倒的に速い
回収もマルチスレッドで処理されるから圧縮フェーズ以外はUIへの影響もなくユーザ目線では実質コストゼロ
良いコードを書いてるなら圧縮もたまにしか起こらないし起こっても大した事ない

423 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 00:26:17.07 ID:vj+h39OC.net]
>>399からの流れを見ればわかるがそういう話ではない
参照カウンタ方式以外のGCは、オブジェクトがどこからも参照されなくなったことが「即座」にわからない
だからRAIIが出来ない、そういう話

もちろん、参照の値が書き換わるたびに毎回マークスイープを実行すれば
即座にゴミが分かるがのでRAII出来るが、マークスイープは重いので参照が書き換わるたびに毎回実行できない
その意味で、循環参照以外のGCは重いと言っている

参照カウンタ方式は軽いので毎回実行できる
即座にゴミが分かるからRAIIが出来る

参照カウンタ方式で問題になるのは循環参照が起こった場合だが
循環参照が発生する箇所は設計段階で分かるので、実際には大した問題ではない
C++であれば、片方をweak_ptrにすればよいというだけの話
そこさえ気を付ければ、参照カウンタ方式とデストラクタの組み合わせは非常にうまく機能する
IDisposableのようなものも要らない



424 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 00:27:10.73 ID:vj+h39OC.net]
>循環参照以外のGCは重いと言っている

↑間違えた

参照カウンタ方式以外のGCは重いと言っている

425 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 00:41:23.52 ID:15KjVKPo.net]
>>413
安全が何で保証されてるのかを知るためにアセンブラを勉強しなさい。
その上で「パフォーマンスは何の問題もない」かどうかを語りなさい。

426 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 00:59:17.81 ID:kBj57j3O.net]
前にも書いたが、RAIIとGCは直接の関係はないよ。
現にC++/CLIでは、ローカルスコープのオブジェクトがスコープを抜けた時点、あるいは
gcnewで作成されたオブジェクトがdeleteされた時点で即座にデストラクタが実行されて
メモリの回収自体はGCで行われる。

427 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 01:02:24.98 ID:MdJCnp0Y.net]
>>415
そもそも不可視のコードでリソースを解放するのが愚行そのもの
プログラマとしての良識があるならusingを使いなさい
RAIIなどというくだらないバッドノウハウはC#では必要ない

428 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 01:31:49.74 ID:vj+h39OC.net]
>ローカルスコープのオブジェクトがスコープを抜けた時点、あるいは
>gcnewで作成されたオブジェクトがdeleteされた時点で即座にデストラクタが実行されて
>メモリの回収自体はGCで行われる。

それはGC関係ないRAIIの話だろ
C#でもusing使えばRAII出来るが
usingも、ローカル変数も、deleteも、何れもGCじゃない
手動で寿命管理しているに過ぎない

寿命管理を自動化(GC)しつつ、RAIIを実現する話をしているわけだが
どんな場合でも、GCで有ろうが無かろうが、手動でデストラクタなりファイナライザなり呼び出せば
RAII出来るに決まっているだろ、それに何の意味が有るんだよ
自動化の話だよ

429 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 01:33:16.88 ID:vj+h39OC.net]
>そもそも不可視のコードでリソースを解放するのが愚行そのもの

その最たるものが、マークスイープ系GCなわけですが
いつ実行されるかすら分からない
まさに不可視

430 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 01:51:43.15 ID:vj+h39OC.net]
極端な話
mallocして使い終わったらfreeして
はい、手動でRAII出来ました!って主張
それ何の意味が有る話なの?ってね

431 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 07:41:27.84 ID:kBj57j3O.net]
>>420
>それはGC関係ないRAIIの話だろ

メモリはGCで回収されると書いたが?あと、そもそもRAII自体がGCと直接関係ないとも書いた。

>usingも、ローカル変数も、deleteも、何れもGCじゃない

いずれもメモリ領域はGCで回収される。

>どんな場合でも、GCで有ろうが無かろうが、手動でデストラクタなりファイナライザなり呼び出せば
>RAII出来るに決まっているだろ、それに何の意味が有るんだよ

ローカルスコープに置いたオブジェクトは手動で呼ぶ必要はない。
gcnewで作成したものにはdeleteを使うってのは普通のC++と同じだ。
ローカルスコープの変数を基点に、スコープを抜けたときに連鎖的にデストラクタが呼ばれて
delete等の後始末がされるってのがRAIIだからな。
普通のC++ではそのdeleteのときにoperator deleteでメモリ領域が解放されるが、C++/CLIでは
GCで回収されるというだけ。

「GCで有ろうが無かろうが」「RAII出来るに決まっている」ということを理解したならまぁそれでいい。
できないってのを否定しただけで、別に意味があるかないかを話していたわけじゃないからな。
要は、GCを使う多くの言語でRAIIができないのはデストラクタの仕組みを持っていないからであって、
それがあるC++/CLIならRAIIも可能ということ。逆にGCを使わない言語でも、デストラクタがなければ
RAIIは不可能。
つまり最初の結論、RAIIとGCの有無に直接の関係はない。

432 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 10:01:03.80 ID:MdJCnp0Y.net]
メモリとその他のリソースを混同して考えるからダメ
まずその他のリソースは不可視のコードで解放しちゃダメ
リソースのスコープは明示的でなければならない
これはデストラクタにもGCにも任せられない
逆にメモリは不可視のコードで解放してもよい
まずこの基本原則から話を進めよう

433 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 10:12:42.93 ID:Ap0rkncx.net]
schemeにはdynamic-windみたいな他所に継続が飛んでも後処理が保証される仕掛けがあるし
デストラクタがない==RAIIできないにはならないと思うの・・・



434 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 11:03:59.82 ID:+zMq83Ww.net]
>>424
んな事はない。
あらゆるリソースの寿命はライブラリでデフォルトの管理がされるべきであり、使用者の完全性を前提にすべきではない。

435 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 11:16:32.31 ID:MdJCnp0Y.net]
>>426
銀の弾丸は無い
あらゆるリソースのあらゆる利用形態に対してデフォルトの動作を定義できるなら話は別だが無理だよね
結局は人が方針を決めて書くしか無い
幸いにしてメインメモリにはRAIIやマークスイープという正解が見つかっているのでそれを使えばいい
だが他のリソースはダメだ

436 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 16:21:42.54 ID:vj+h39OC.net]
>>423
そんな基本的なことを言って何がしたいの?

RAIIとGCは密接な関係が有るんだよ
君はローカル変数が好きみたいだから、ローカル変数の事例で説明するとする
(嫌ならC#のusingと読み替えてもらっても構わない)
ローカルに確保したオブジェクトが、メンバ変数に他のオブジェクトを持っていたとする
いわゆるコンポジションの状態、よくある話
C++で言えば、class my_class{ object *obj; }; といった感じのクラスになる、分かるよね?
で、ローカル変数はスコープを抜けたら解放される、usingも似たようなもの、これはRAIIの基本、良いね?
このとき、マークスイープ系GCだと、my_classのobjに他からの参照が有るかどうか、即座にわからないので
objを開放してよいのか判断が付かない→my_classは破棄されてもobjはGC発動まで保留される→objは残るのでRAIIの意味がない

もしくは、my_classのobjに他からの参照が全く無いことをプログラマが保証して
my_classの開放部にobjをdeleteなりdisposeなりするコードを記入する
しかしこれは、objの所有権がはっきりしていないことには使えない上に、「手動」である
C++の場合はスマポが有るのでまだましだが、C#のDisposeは完全に手動で呼ばなければならない
自身のメンバにIDisposableなメンバいたら、自身もIDisposableにしなければならず、Disposeメソッドを実装して
自身のメンバのDisposeを芋づる式に呼び出すコードを手動で書かなければならない
mallocしたらfreeしましょうと一緒で、C言語レベルの全くの手動になってしまう

参照カウンタ方式のGCではこれらの問題は発生しない
他からの参照が有るか無いかは即座にわかるし、参照カウンタが0になれば、その場で即座に破棄される
自身のメンバに対して、デストラクタは芋づる式に呼び出されるので、C#のDispose実装のような面倒さは無い

>>424
お前言ってること無茶苦茶すぎるだろ

>リソースのスコープは明示的でなければならない、デストラクタにもGCにも任せられない

GCはともかく、デストラクタでもダメって意味不明すぎるんだが
考えの根本がおかしい

437 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 16:43:31.54 ID:vj+h39OC.net]
C++で書けば
struct A{ *obj };
void func()
{
  A a;
}
こういったRAIIの場合のobjの開放はどういう扱いにするんだって話

aが完全にobjを所有しているケースなら、Aのデストラクタにdelete obj;とでも書くかscoped_ptrでも使えばよい
しかし、objが彼方此方から参照されている可能性もあるので
そこんとこコンパイラは判断が付かないので、自動化はきない
あくまで、プログラマが保証する形になる
C#のDisposeのような仕組みを言語側で用意したところで、自身のメンバにIDisposableなメンバが有るかどうか
いちいち調べなきゃならなないし、調べ忘れや呼び出し忘れをするという問題が出てくる
しかも、所有権が単一である場合にしか成り立たない

一方でマークスイープ系GCに任せっぱなしにすると、objの開放はGC発動まで遅延してしまうだろう

参照カウンタはこれらの問題をすべて解決する
参照数はどのタイミングでも直ぐに分かるし、0になれば遅延なしで即座に削除される
デストラクタは自身のメンバに対して芋づる式に自動で呼び出されるので
スマポを使っておけば呼び出し忘れるということもないし
Disposeのような冗長なコードを書く必要もない

438 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 16:44:43.86 ID:vj+h39OC.net]
訂正

struct A{ *obj };
void func()
{
  A a;
}



struct A{ object *obj };
void func()
{
  A a;
}

439 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 17:07:08.54 ID:vj+h39OC.net]
結局、C#のDisposeはどこまで行ってもどんなに進化しても手動で書かなければならない
自身のDisposeが呼ばれたからと言って、自身のメンバ変数のDisposeを芋づる式に勝手に呼び出して良いかは
コンパイラにはまったく判断が付かない
他からも参照されていて今まさに使われている可能性がある以上
コンパイラが勝手に自動でDisposeを呼び出すコードを生成することはできない
GCを発動してみるまでは、どこからも参照されなくなったことが保証できない
しかし、GCの発動まで開放が遅延しても良いのであれば、そもそもDisposeは要らないわけで
Disposeの実行はGC発動より先行していなければならず、GCに頼れないということになる
なので、自身のDisposeが呼ばれたときに、自身のメンバのDisposeをしてよいかは
プログラマが考え、手動で呼び出す必要が有る
所有権が単一であれば、手動でメンバのDisposeを呼び出せばよい
手動で記述しなければならないので面倒くさいし、ミスの元ではあるが、一応できる
所有権が複数であれば参照カウンタを使うしか現実的な方法は無いだろう
マークスイープ系GCなのに参照カウンタで独自に管理するのは馬鹿げているがな

参照カウンタ方式+デストラクタ
であればこれらの問題は一切発生しない
参照カウンタが0になったことは即座にわかるし、デストラクタはメンバ変数に対して芋づる式に呼び出されるので
開放に関しての特別なコードを手動で書く必要は無い
開放処理も一本化される

440 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 17:16:20.56 ID:UGnRhUEw.net]
長文は漏れなく基地外

441 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 17:17:01.33 ID:MdJCnp0Y.net]
>>428
バカすぎる
細かい事気にせずデストラクタで解放すりゃそれでおkって感じの適当な現場でしか働いた事無いんだろうな

442 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 17:22:53.59 ID:/D0vdPDd.net]
ポインタがメンバ変数になってたら公開しちゃいかんでしょ

443 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 17:24:21.54 ID:MdJCnp0Y.net]
まずDisposeは生成できる
めんどくさいという奴は知識が無いだけ

リソースを共有する事は少ない
というか設計段階で可能な限り少なくする
そして共有するならするでしっかり管理して自動解放などという手抜きはしない
基本中の基本だ



444 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 17:32:09.52 ID:+zMq83Ww.net]
デストラクタで解放してはいけないリソースをデストラクタで解放しなければいいだけで、デストラクタで解放すればいいリソースはデストラクタで自動的に解放すべき。

445 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 20:12:26.78 ID:kBj57j3O.net]
>参照カウンタ方式+デストラクタ
>であればこれらの問題は一切発生しない

.NETのマーク&スイープGCの上でRAIIを実現している実例としてC++/CLIを説明したんだが、
「基本的なこと」とか言いながら結局何も理解してないんだな。

そもそもRAIIの話で所有権が共有されたオブジェクトを持ち出すのが意味不明すぎる。

>参照カウンタが0になったことは即座にわかるし、

「いつか」全員が所有権を手放したら「即座に」破棄される
「いつか」全員が所有権を手放したら「いつか」GCで破棄される

どう違うというのか。

446 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 20:35:08.73 ID:Ng/EIIMI.net]
RAII信者の痛さは異常
オブジェクトをコピーされたら破綻するのに

447 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 21:10:56.38 ID:N7IGtcj3.net]
グローバルインスタンスホルダーは明確にインスタンスの状態を把握したいときに積極的に使うべき

448 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 22:32:53.86 ID:vj+h39OC.net]
>「いつか」全員が所有権を手放したら「即座に」破棄される
>「いつか」全員が所有権を手放したら「いつか」GCで破棄される
>どう違うというのか。

少なくとも最善が尽くされるという意味で違うし
同じデータと同じプログラムで有れば、常に同じタイミングで開放処理が走るという再現性が有る

それから、自分しか所有権を持っていない場合、つまり参照数が常に1というシンプルな状況ですら
参照カウンタ方式の方が開放処理が自動化されて楽

参照カウンタ方式で有れば、スマポを使っておけば済む
scoped_ptrでも良い

マークスイープ系GCであれば、自身しか所有権を持たない単純な場合でも
非常に面倒なことになる
自身にDisposeを実装して自身のメンバのDisposeを呼び出すコードを手動で書かなければならない
何故こういったコードをコンパイラが自動生成できず、手動で書かなければならないのかの根底に
まさにマークスイープGCの存在が有る
マークスイープ系GCは何処からも参照されなくなったことがその場ですぐに分からない
GCを発動してみるまで保証することが出来ない

自分のDisposeが呼び出された、まさにその瞬間に、自分のメンバに対してもDisposeしてよいのかどうなのか
参照数がリアルタイムで即座に分からないので判断する材料が何も無く
コンパイラはC++のデストラクタのように自動で芋づる式に開放処理を呼び出すコードを生成することが出来ない

要するにマークスイープ系GCではDisposeのコンパイラによる自動生成が出来ないという大きなマイナスが有る

449 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 22:36:05.37 ID:15KjVKPo.net]
>>438
しねーよ

450 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 22:41:25.16 ID:VNvh7E4d.net]
>>440
子要素をDisposeしていいかどうかもわからないってそりゃ設計サボってる以外のなんでもないだろう
ちゃんと設計してればいつ削除してよいかなんてわかるはずだろ
まともに設計もできないレガシーエンジニアは黙っててよ
設計に時間使わないとリソース云々以前に別のバグだらけになるぞ

451 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 23:42:37.04 ID:Ng/EIIMI.net]
RAII信者は頭が悪いな

452 名前:デフォルトの名無しさん mailto:sage [2016/03/27(日) 23:59:39.99 ID:15KjVKPo.net]
>>443
自分の頭を検証しな

453 名前:デフォルトの名無しさん mailto:sage [2016/03/28(月) 00:10:58.97 ID:h9yZCrPP.net]
メンバにDispose持たせる設計って大抵ダメだよね



454 名前:デフォルトの名無しさん mailto:sage [2016/03/28(月) 00:20:40.85 ID:j/beyn8U.net]
>>440
前者(参照カウントGC)はRAIIができるが後者(マーク&スイープGC)ではできないというお前の
主張について言っているんだが?
「最善が尽くされる」からRAIIができて、尽くされないからRAIIができないとでも言うのだろうかw

>要するにマークスイープ系GCではDisposeのコンパイラによる自動生成が出来ないという大きなマイナスが有る

何度も例に挙げているC++/CLIでは、デストラクタを記述するとコンパイラによってDisposeが追加される。
そして、ローカルスコープに置いたオブジェクトに対してはスコープを抜ける際に自動的にdeleteが呼ばれる。
そこからdelete→Dispose→デストラクタと呼び出される。RAIIに必要なものは揃っているし、事実、可能だ。
もちろん、そのメモリ領域は別のタイミングでGCによって回収される。

ここまで説明しても理解できない低脳ならしょうがない。
やはりデストラクタとファイナライザの違いが理解できてないようだからそこから勉強しなおせ。

455 名前:デフォルトの名無しさん mailto:sage [2016/03/28(月) 00:39:52.48 ID:2h3yopdG.net]
{
std::shared_ptr<my_namespace::my_class> p(new my_namespace::my_class(...));
/* unko_code */
}

using(var obj = new MyClass(...)) {
/* GoodCode */
}

美しいという事はいい事だね
C#は書いてある事がシンタックス的にもセマンティック的にも明確だ
リソース管理はこうでなければならない

456 名前:デフォルトの名無しさん mailto:sage [2016/03/28(月) 01:22:52.25 ID:khgTmo3F.net]
>>447
C++にもusing使えやw いらない波括弧外せやw

457 名前:デフォルトの名無しさん mailto:sage [2016/03/28(月) 03:34:15.37 ID:d3YBhLBG.net]
>>447
usingの方が全然明確だね
objがコピーされてても問題ない
RAII脳ではわからないんだろう

458 名前:デフォルトの名無しさん mailto:sage [2016/03/28(月) 03:36:11.96 ID:d3YBhLBG.net]
schemeに何十年も前から存在するwith-xxxx 系を一般化した構文だね

459 名前:デフォルトの名無しさん mailto:sage [2016/03/29(火) 01:23:53.57 ID:Qm5oX8hY.net]
アレを更にtypedefされたりされると
ワケワカランくなるよな

460 名前:デフォルトの名無しさん mailto:sage [2016/03/29(火) 01:50:13.51 ID:40IzaG0J.net]
c++なら普通こうだな
{
my_class obj(...);
...
}
そういやc#でp.release()相当の事って簡単にできるの?
{
auto p(make_unique<my_class>(...));
...
}
nullって代入可能?

461 名前:デフォルトの名無しさん mailto:sage [2016/04/04(月) 02:47:24.69 ID:+1V6ohqL.net]
GCがあるのになぜJavaはメモリリークしまくるソフトウェアを量産するのか

462 名前:デフォルトの名無しさん mailto:sage [2016/04/04(月) 02:55:18.29 ID:FhdBY7IF.net]
>>453
Javaだから

463 名前:デフォルトの名無しさん mailto:sage [2016/04/12(火) 23:15:42.48 ID:ZWvwh7J9.net]
Rust使えばいいのさ



464 名前:デフォルトの名無しさん mailto:sage [2016/04/13(水) 10:33:47.16 ID:+hJ3fPVS.net]
>>455
会社にいるよな、そういうやつ

465 名前:デフォルトの名無しさん mailto:sage [2016/04/13(水) 15:29:31.16 ID:oOcEPJTu.net]
GC大好きっ子に聞きたいんだが
完璧な(理想的な)GCを搭載したメジャーな言語処理系って何があるの?
これで開発すればリークも管理も気にしないでOKってやつ

466 名前:デフォルトの名無しさん mailto:sage [2016/04/13(水) 16:22:35.14 ID:s5MRiDQ8.net]
無い

マークスイープ系GC → 循環参照OK、しかし即座に開放されない
参照カウンタGC → 即座に開放される、しかし循環参照NG

ということで、理想のGCは無い
全てのGCは何かを妥協している

それから、たとえGCを使ったとしても
要らなくなったオブジェクトの参照をいつまでも握っている奴が居たら解放されないから
リソースの管理をしなくてよいということは無い

あと、GCは基本的にメインメモリに対してしか有効に機能しないから
例えばファイルオブジェクトなんかは要らなくなったら即座にcloseするなりすべきで
リソース管理フリーというわけにはいかない

467 名前:デフォルトの名無しさん mailto:sage [2016/04/13(水) 16:54:16.68 ID:s5MRiDQ8.net]
つまりは、GCを使っていたとしても
君がオブジェクトを何処かに登録したなら
オブジェクトが要らなくなったら登録解除してあげないと
そのオブジェクトは解放されないのだ
これはちょうどmallocしたらfreeしましょうに似ていて
GCを使ったとしても全てのリソースの管理が自動になるわけではないということだね



468 名前:極的にはGCの利点は自分でfree/deleteをしなくても良いところにある
これはつまり、ダングリングポインタが発生しないということだ
[]
[ここ壊れてます]

469 名前:デフォルトの名無しさん mailto:sage [2016/04/14(木) 20:54:37.84 ID:f1hhftJp.net]
>>457
C+BoehmGC

470 名前:デフォルトの名無しさん [2016/04/17(日) 16:17:55.58 ID:j/f/oFPY.net]
そして無視されてしまうコピーGC君
GCの利点は自分で大量にメモリの確保&解放するプログラムにおいてバグが出にくくスループットも出るってところだと思う
もしheapをそんなに頻繁に確保&解放しないんだったらGCない言語の方がいい
ただ近代的な言語は少数の例外を除いて大抵GC積んでるけど

471 名前:デフォルトの名無しさん [2016/04/17(日) 16:21:44.96 ID:j/f/oFPY.net]
>リソース管理フリーというわけにはいかない
リソース管理フリーについてはrustみたいなGCない言語のほうが達成できてるよね(あとは関数型言語か)
でもrustでもリソースの解放時にエラーを吐く可能性がある処理なら自分で解放する処理書かなきゃいけないっぽいけど

472 名前:デフォルトの名無しさん mailto:sage [2016/04/17(日) 18:35:17.89 ID:SAR9JCaP.net]
RAIIでも結局どのタイミングで解放されるか意識しなくてもいいってわけじゃないし
リソース解放処理を書かなくていいだけで

473 名前:デフォルトの名無しさん mailto:sage [2016/04/17(日) 18:43:59.82 ID:cFoKw8Zx.net]
メモリ管理系のバグが顕在化しにくいだけで、そこら辺適当なまま中途半端にキャリアを積む開発者を量産するという害悪が大きい。
JNIやらで他のAPI使う必要が出てくると結局いろいろ配慮しなきゃいけなくなるし。



474 名前:デフォルトの名無しさん mailto:sage [2016/04/17(日) 19:43:44.44 ID:oNE1M7I6.net]
>>460
コンサバじゃ完璧にほど遠いぞな

475 名前:デフォルトの名無しさん mailto:sage [2016/04/17(日) 19:50:47.36 ID:1R/4ebGS.net]
>メモリ管理系のバグが顕在化しにくいだけ
結局これだよね
本当に丸投げできるなら乗っかるのもいいと思う
性能問題はハードの進化で一部の用途を除けば問題無くなると思うし
でも現実は中途半端だから意識して書いたほうがマシだと

476 名前:デフォルトの名無しさん [2016/04/17(日) 21:19:09.59 ID:IB74e9ph.net]
ムーブセマンティクスのおかげでずいぶん便利に。

477 名前:デフォルトの名無しさん mailto:sage [2016/04/17(日) 23:09:38.99 ID:j/f/oFPY.net]
あと正確にはGCには含まれないけどメモリコンパクションをやってくれる処理系が多いのも
GCを使う利点になるかも

478 名前:デフォルトの名無しさん mailto:sage [2016/04/17(日) 23:17:23.70 ID:cFoKw8Zx.net]
今どき意図的にやらない限りメモリフラグメンテーションで困るような場面があるか?
アドレス空間も余裕出てきたし、多少おかしな確保パターンで浪費してもGCほど実メモリを食わないし。
今どき主流のサイズ毎に空きを管理するmallocは優秀だしね。
これがダメならlinuxカーネルとか先に落ちちゃうぞ。

479 名前:デフォルトの名無しさん [2016/04/18(月) 15:56:44.18 ID:kcE0qDSU.net]
>>469
昔、C/C++を駆使して日本が誇るスパコン京に投入するタスクセットを書き上げたのだが
実行するとどうも性能が出ない。
色々調べた結果、どうやらメモリーが断片化していることが分かった。
そこで多大な投資を行いJavaで書き直したらなんと100倍も性能が上がったのです!
これが>>468さんの経験してきたことなんです。

480 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 16:30:17.23 ID:BDPQ12Es.net]
自前のメモリ管理が超下手くそなだけやろ
修業して出直してこいや

481 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 16:37:09.21 ID:OvHIqTOi.net]
自慢になってないような

482 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 16:44:52.62 ID:9yQABY6F.net]
ゲームだとフラグメント問題になること多いよ
ゲーム専用機なら特に
最近は特にオープンワールドが当たり前になってるけど
あれストリーミングでどんどんメモリ置き換えていくしね

483 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 16:47:31.98 ID:/wa5LIj ]
[ここ壊れてます]



484 名前:H.net mailto: jemallocのようなモダンなmalloc実装使えば良かったのでは。 []
[ここ壊れてます]

485 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 17:47:00.91 ID:IBBVu28x.net]
ゲーム専用機でフラグメンテーションおこすとか開発者としての適性を疑われても不思議ではない。
オブジェクトの寿命管理すらしないのか?

486 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 18:51:08.61 ID:RPQ9NKJO.net]
メモリのフラグメンテーションをC/C++でコントロールする方法ってあるの?
mallocの実装頼りじゃなく。

487 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 19:05:27.63 ID:OvHIqTOi.net]
mallocの挙動がわかってれば、ある程度は・・・・

488 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 19:14:30.71 ID:OvHIqTOi.net]
細かくメモリ要求するから、下回りで時間がかかる
メモリ分断されてもオンメモリでの検索はさほど時間がかからない
(空きができても、そこに入らないときに)

489 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 19:15:14.97 ID:9yQABY6F.net]
>>475
フラグメンテーションって何かわかってないでしょ?
寿命管理だけでは解決できないよ

490 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 19:21:39.69 ID:IBBVu28x.net]
寿命管理で解決できないとか、フラグメンテーションがどういう現象か分かっているの?

汎用の寿命管理APIみたいなのを使うとか言うのと勘違いでもしている?

491 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 20:02:22.75 ID:3yZKjOEp.net]
>>480
おいおい・・
この場合寿命を管理できないってのはgiven conditionとして考えないと
そりゃ寿命があらかじめわかってるなら苦労しないっての
大規模なプログラムでそんな恵まれた状況は例外的だよ

492 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 20:57:42.92 ID:IBBVu28x.net]
専用ゲーム機上のゲームだよ。
リソースが逼迫したら何を優先するかの戦略も含めてほぼ理想的なgiven conditionだろうに。
ユーザーの行動による不確定性も全てコントロール下にあるだろうに。

493 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 21:13:59.16 ID:RPQ9NKJO.net]
>>482 専用ゲーム機と普通のPCの1アプリケーションとで何が違うのか。mallocも使わないってこと?
NoGC, 各GCでメモリ空間がどう使われるかを視覚化
ttps://spin.atomicobject.com/2014/09/03/visualizing-garbage-collection-algorithms/
黒: 未使用
灰: 確保
緑: 読み込み
黄: 書き込み
赤: GC用のアクセス(参照カウンタ、マーク用ビットetc)
緑と黄は時間経過で退色していく

メモリフラグメンテーションという観点から見ると、コピー型GCが綺麗。



494 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 21:15:59.31 ID:3yZKjOEp.net]
まぁテトリスとかならその程度の理解でいいんじゃない?w

495 名前:デフォルトの名無しさん [2016/04/18(月) 21:33:24.92 ID:kcE0qDSU.net]
Javaの寿命管理APIは最強ですな。

496 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 21:49:39.41 ID:9yQABY6F.net]
>>482
GTAみたいなゲーム考えてみ?
あれ全てオブジェクトの寿命を事前に決められると思う?
原理的には不可能じゃないだろうがそんな職人的な作りしてたら開発に10年かかるわw

497 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 21:56:15.95 ID:IBBVu28x.net]
普通のmallocで足りるならそれでもいいけど。
基本メモリ容量ギリギリまで使うから、最初に描画、ゲーム内部状態、音声、ディスクキャッシュなどでどのくらい使うか決めておく。
終始一貫して静的に決めるのが楽だけど、場合によっては場面ごとに配分を切り替えたりする。
で、例えば広いマップ上を自由に動き回るようなゲームだと、マップを複数のパーツに分割して、詳細モデルから簡易モデルまで用意する。

498 名前:デフォルトの名無しさん mailto:sage [2016/04/18(月) 22:12:01.61 ID:3yZKjOEp.net]
ゲームプログラムとかならメモリ確保は直接システムコール呼び出して
ページ単位でアロケートするのが定石
必要ならmspaceとかインスタンスベースのヒープを自分で作る

499 名前:デフォルトの名無しさん mailto:sage [2016/04/19(火) 01:49:46.30 ID:KVIhh3Hm.net]
使用できるメモリのサイズも空きメモリのサイズも最初か

500 名前:ら分かってて、ユーザーからの入力も限られてて、
そいつら全部自分で管理できる「恵まれた」環境でしか通用しないアプローチだよなそれ。
[]
[ここ壊れてます]

501 名前:デフォルトの名無しさん [2016/04/19(火) 01:58:46.65 ID:fq3yh1do.net]
レーシングゲームは出てくる車が決まっていてコースも決まっているから。

502 名前:デフォルトの名無しさん mailto:sage [2016/04/19(火) 08:28:57.71 ID:YcewE61x.net]
昨今はレースゲームでも汎用的なゲームエンジン使うことが多いから
その場合事前に寿命が決まってる前提の作りにはしていないと思うぞ
GDCとかGame Gemとかでも昔からフラグメンテーション対策を含む
メモリ管理の手法はいろいろ議論されているから調べてみるとよろし

503 名前:デフォルトの名無しさん mailto:sage [2016/04/20(水) 12:56:58.01 ID:r07pzD8i.net]
>>489
ハードリアルタイムなシステムならごく普通
って言うかそうでないと作れない



504 名前:デフォルトの名無しさん mailto:sage [2016/04/20(水) 13:09:41.53 ID:DLw9rf+F.net]
>>486
ああいうFPSのオブジェクトは全部管理されてるし
gcなんか使ってないよ

505 名前:デフォルトの名無しさん mailto:sage [2016/04/20(水) 19:22:46.02 ID:bj66dBvK.net]
>>493
フラグメンテーションの話だっての

506 名前:デフォルトの名無しさん mailto:sage [2016/04/20(水) 19:58:58.01 ID:CuR1I1mj.net]
やり手のゲーム系の方たちに、逆らうようなことは・・・・

507 名前:デフォルトの名無しさん mailto:sage [2016/04/21(木) 01:20:25.83 ID:jf1w54Av.net]
>>494
そんなのどうにでもなるでしょ
汎用のmallocなんかとは事情が違う

508 名前:デフォルトの名無しさん mailto:sage [2016/04/21(木) 02:16:29.96 ID:G+xv7xqn.net]
>>496
どうとでもなるって?
へーじゃあ試させてもらうわ
GDC 2016でもこういう講演があった
schedule.gdconf.com/session/building-a-low-fragmentation-memory-system-for-64-bit-games
64bitならなぜフラグメンテーションが軽減できるか説明してもらおうか?
物理メモリが多いからじゃないからな
あればあるだけメモリ使うのがゲームなのでメモリに余裕があるわけじゃない

509 名前:デフォルトの名無しさん mailto:sage [2016/04/21(木) 11:32:02.27 ID:EjzxVVPK.net]
ゲーム機含む組み込み系は結果が不確定な動的メモリー確保なんかしないのが鉄板(しようとする奴は未熟な馬鹿)だったが
PCと合わせて組み込み機器もスペックが潤沢になって富豪的プログラムが一般的になってきたからね

無知ゆえ聞きたいんだが
最近のゲームソフトやら>>497やらってどういうGC使ってるの?

510 名前:デフォルトの名無しさん mailto:sage [2016/04/21(木) 13:09:31.92 ID:pog3nPgL.net]
ゲームだって組込みだって今どき動的メモリー確保しないなんて化石みたいな発想が通るわけないだろ
かといって普通のGCは問題外
賢いメモリアロケーションをするしかないんだよ
>>497は「こんなすごい講演するぞ」って言う宣伝だけだけど中身はどこにあるの?

511 名前:デフォルトの名無しさん mailto:sage [2016/04/21(木) 16:14:15.43 ID:lEi5GQja.net]
>>497
MMUが付いているから

物理メモリがフラグメンテーションすることは、ある程度これで防げる
しかもハードウェアの機能だから高速だし、勝手にやってくれるから素晴らしい
速度が重要なゲームでは、これは有り難い
ソフト的なアプローチでこれ以上の細工は遅くなるだけで効果が薄い

問題は論理アドレスの方
32bit空間だと例え物理メモリが余っていても
論理アドレスがフラグメンテーションを起こして連続したメモリを確保できなくなる
物理アドレスが枯渇するよりもさきに、そちらの方が問題になることが多い
64bitだと、これが防げる

512 名前:デフォルトの名無しさん mailto:sage [2016/04/21(木) 16:37:13.61 ID:lEi5GQja.net]
各ゲーム機の事情は知らないが
PCで有れば、64bitプロセスは、論理アドレスの空間が256TB(48bit)もある
ゲーム機も似たようなものだろう
256TBもの物理メモリを積んだPCやゲーム機は存在していないし
例え論理アドレスが激しくラグメンテーションを起こしても
256TBもの論理アドレス空間を使い切るという事態は考えなくてよい
つまり、64bitプロセスなら、論理アドレスの心配はしなくてよい

一方で、物理アドレスのフラグメンテーションはMMUに任せておけばよい
これはハードウェアで自動で行われるし、とても高速
その余計にソフトウェア的アプローチで頑張ってみたところで
多少物理メモリのフラグメンテーションは改善されるかもしれないが
徒労というかなんというか、労力に見合わないし
しかも遅くなるのでゲームには向いていないし、やらなくてよい
物理アドレスは自分だけが使っているわけではなく、OSを含めたほかのプロセスも使っているので
自分のプロセスが使っている物理メモリだけフラグメンテーションを解消しようと
コンパクションするのも何か完璧感が無いし
自分のプロセス内だけで考えても、外部ライブラリやXBoxならDirectXが使用している物理メモリの
フラグメンテーションは手が出せないので解消しようがない、やはりやるだけ徒労
自分の管理出来る部分だけ物理メモリのコンパクションをかけても
「これで計算上、必ずあと200MBの物理メモリを使用できる筈」とかといった保証はどこにもない
理由は、外部のライブラリ内での物理メモリの使用状況が分からないし、手が出せないから
とにかく徒労であり、MMUに任せておけばよい

513 名前:デフォルトの名無しさん mailto:sage [2016/04/21(木) 17:22:28.74 ID:7dcTEyv0.net]
ただの物理メモリ不足の話がなんでと思ってしまった
swapはじまったら、fpsなゲームはどうなるんでしょうね



514 名前:デフォルトの名無しさん mailto:sage [2016/04/21(木) 19:18:25.46 ID:zEEe/DNn.net]
論理アドレスが64bitだったらフラグメンテーション対策なんていらんということ?いや自分もそうは思うんだが。
上の方で「専用ゲーム機開発ならフラグメンテーション対策も行うのが常識!」みたいに主張してる人がいて、
それって自作のmalloc相当のアロケータ作るってことだよね?と思ったんだが、
メモリ節約術とごっちゃにしてる人もいてわけが分からなくなってきた。

515 名前:デフォルトの名無しさん mailto:sage [2016/04/21(木) 22:14:27.41 ID:WHT47icf.net]
なんで馬鹿に限って長文書きたがるんだろうか






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<210KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef