- 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/
- 381 名前:デフォルトの名無しさん [2016/02/10(水) 11:29:59.19 ID:lL2Wg2mH.net]
- Javaは強制的に解放させることもできるようにすべきだったな。
- 382 名前:デフォルトの名無しさん mailto:sage [2016/02/10(水) 11:41:46.63 ID:83b7Yxnh.net]
- Java(VM)は(すべてのプラットフォームで)強制的に解放させることもできるようにすべきだったな。
- 383 名前:デフォルトの名無しさん mailto:sage [2016/02/10(水) 12:19:44.29 ID:k9iR7lzz.net]
- 都度メモリ管理するよか、GCに任せた方がスループット的に有利な場合も多いでしょ。
- 384 名前:デフォルトの名無しさん mailto:sage [2016/02/10(水) 14:29:59.29 ID:CcpqYYAq.net]
- GCはメモリ管理に関しては成功してる、
でも、メモリブロックをオブジェクトに昇格させたにも関わらず、相変わらず「メモリ管理」だから失敗。
- 385 名前:デフォルトの名無しさん mailto:sage [2016/02/10(水) 17:29:46.71 ID:+sMp0qjD.net]
- そうそう、メインメモリの管理に関しては100%成功している
しかし、今やメインメモリはそれほど貴重なものではないわけだがな コンシューマでも数十GB積んでたりは珍しくない メインメモリがなくなるより他のリソースが枯渇する方が現実的 だからメインメモリ以外のリソースに関しては使い終わったら即座に開放してほしいから GCとは別にRAIIを行う仕組みを導入するわけだが 真剣に考えていくと、RAIIはGCと相性が悪い そもそも使い終わったら自動で即座に開放(RAII)できるなら全てのGCはそう実装すべきで それが出来ないからわざわざコストのかかるマークスイープを遅延して実行しているわけだからな C++みたいにGCを参照カウンタ方式にして、プログラマが人力で循環参照が無いことを保証する以外に あちこちから参照されるオブジェクトのRAIIを自動化する方法は無い
- 386 名前:デフォルトの名無しさん mailto:sage [2016/02/10(水) 20:59:51.38 ID:rEABlirv.net]
- JAVAはクソ
- 387 名前:デフォルトの名無しさん mailto:sage [2016/02/10(水) 21:00:45.91 ID:ZQ/yQmxu.net]
- 簡単だよ
スレッド立ててGCをフルサイクル実行し続けるだけ
- 388 名前:デフォルトの名無しさん mailto:sage [2016/02/11(木) 16:22:39.56 ID:vxbPXQEr.net]
- javaもsandy-bridge以降でSSDとかならそれほど重いってわけじゃないけど
相変わらずatomでeMMCだったりする環境も並行して存在してて そこで動かすと改めて糞だと思うわけよ GCが悪いんじゃなくてjavaランタイムが悪いんだろうけどね
- 389 名前:デフォルトの名無しさん mailto:sage [2016/02/11(木) 19:04:56.18 ID:EuRhj+pR.net]
- フラッシュとJAVAは、システムに見つかり次第、速攻アンインストールしている
- 390 名前:デフォルトの名無しさん mailto:sage [2016/02/12(金) 08:32:20.35 ID:Uwfak+5B.net]
- >>377
Pythonみたいに参照カウント+GC(循環参照を解放するため)が最強ってこと?
- 391 名前:デフォルトの名無しさん mailto:sage [2016/02/13(土) 15:34:22.04 ID:OKKAbu21.net]
- 最近のPC環境でも贅沢が過ぎるプログラムは動かん。
最近の奴だと、Node.jsのパッケージマネージャnpmが`npm search`と初回に打つとパッケージ検索用のインデックスを作ろうとするんだけど、 1つのjsonオブジェクトにまとめようとするからかOOMエラーを吐いて失敗するっていう不具合。 npmに登録されてるパッケージ数が膨大になったせいもあるが、設計を間違えると遅いどころか動かなくなる。
- 392 名前:デフォルトの名無しさん mailto:sage [2016/02/13(土) 22:32:48.48 ID:6Xm9VASh.net]
- GCがある言語でRAIIみたいな事したいのなら
loan patten使えばいいだけでは
- 393 名前:デフォルトの名無しさん mailto:sage [2016/02/13(土) 23:42:47.95 ID:VLo29AwR.net]
- リソースを共有した上で最後の参照が切れた時点で回収してほしい
しかし誰が共有するかもその寿命も実行時までわからない そういう前時代的なダサい設計をした時の話しなんだろ Loan Patternはこの状況では役に立たない
- 394 名前:デフォルトの名無しさん mailto:sage [2016/02/14(日) 00:56:38.97 ID:mwiD0ozs.net]
- しかし、言語側は、そういうダサい設計も許さないといけないので
マークスイープ系GC搭載で、循環参照が有っても良いことが前提になっている言語で 「使い終わったら自動で即座に開放」を実現するのは困難 そんなことが可能なら、マークスイープは要らないからな
- 395 名前:デフォルトの名無しさん mailto:sage [2016/02/14(日) 19:42:04.72 ID:I7Qc+kxz.net]
- 循環参照なんて放置すればいいの
どうせプロセスが終了すればOSが開放してくれるの
- 396 名前:デフォルトの名無しさん [2016/02/14(日) 20:10:25.23 ID:EqhxGdNa.net]
- >>387
Windowsのように定期的に再起動しなければいけないソフトウェアができあがっちゃいそう
- 397 名前:デフォルトの名無しさん mailto:sage [2016/02/15(月) 18:16:17.47 ID:TvNTryet.net]
- ErlangでOS作るか
- 398 名前:デフォルトの名無しさん [2016/02/15(月) 19:50:44.55 ID:L+A+Kd2h.net]
- そこはRustで
- 399 名前:デフォルトの名無しさん mailto:sage [2016/03/01(火) 15:00:17.89 ID:QERDe7Jh.net]
- 5分でわかるガベージコレクションの仕組み
https://geechs-magazine.com/tag/tech/20160229
- 400 名前:デフォルトの名無しさん [2016/03/23(水) 02:31:06.32 ID:MFzvJNSi.net]
- 常識的に考えてカーネルの実装にはGCなんて使えないし
業務アプリケーションではパフォーマンスより開発速度がはるかに重要になる 結局適材適所だ GCを強制されるのは苦痛だが使えないのも苦痛だ 好きな時に使える言語がいいよね!
- 401 名前:デフォルトの名無しさん mailto:sage [2016/03/23(水) 03:41:39.64 ID:SoMbpeP6.net]
- パフォーマンスが問題にならないGCが一つだけあって、それが参照カウンタ方式のGC
パフォーマンスが問題にならない→即座に逐一削除できる→RAIIが出来る 非常に強力だがプログラマが循環参照が無いことを保証しなければならない しかし、循環参照が発生する場合は設計段階で分かるのでそれほど深刻では無いのだ!
- 402 名前:デフォルトの名無しさん mailto:sage [2016/03/23(水) 03:47:03.14 ID:VzK80P8k.net]
- androidでもう何も判らん状態でプログラミングして
それなりに動くのができたからおれは許したよ でもサービスまで勝手に回収されちゃうとは思わなかったわ アホだろグーグル
- 403 名前:デフォルトの名無しさん mailto:sage [2016/03/23(水) 07:53:14.58 ID:JT2FURwc.net]
- RAIIに必要なのはデストラクタが呼ばれることであって実際にメモリが解放されることじゃないから
GC言語でもRAIIができないわけじゃない。
- 404 名前:デフォルトの名無しさん mailto:sage [2016/03/23(水) 10:07:19.06 ID:SB04Y3rp.net]
- RAIIに必要なのは適切なタイミングで確実に解放処理が呼ばれることであって
いつ呼ばれるかわからないデストラクタではだめ
- 405 名前:デフォルトの名無しさん mailto:sage [2016/03/23(水) 18:24:05.29 ID:jWiL+V+6.net]
- かつてStandard MLの実装で、GCじゃないメモリ管理方法をやってみたのがあったな。
コンパイラが全部自動でやるからコードの見た目はSMLなんだけど、いざ動かすとGCより遅かった。 ある程度プログラマがリソース管理のためのヒントを与えないと、GCを捨てられない。
- 406 名前:デフォルトの名無しさん mailto:sage [2016/03/23(水) 20:05:29.02 ID:JT2FURwc.net]
- >>396
おまえが言っているのはファイナライザ。 それと、デストラクタはメモリの解放なんかしないよ。デストラクトするだけ。
- 407 名前:デフォルトの名無しさん mailto:sage [2016/03/23(水) 21:43:30.89 ID:SoMbpeP6.net]
- この際、呼び名はどうでも良い
参照カウンタ方式以外のGCでは、どこからも参照されなくなったことが、即座にはわからない だから、自動で即座に開放関数を呼び出すことが出来ない→RAIIが出来ない C#で言うところのusingみたいに、プログラマが手動で情報を与えるなら出来る だが、usingはGCでは無い
- 408 名前:デフォルトの名無しさん mailto:sage [2016/03/24(木) 00:53:54.57 ID:smGLwjga.net]
- いまさら、ゲームキューブ叩いてどうするんだ?
- 409 名前:デフォルトの名無しさん [2016/03/26(土) 05:40:22.28 ID:vD3g1idC.net]
- >>393
間違い マークスイープのように負荷が集中しないだけでありパフォーマンスへの影響はある 特にツリー状のデータついてルートが削除された時子要素もデクリメントする必要があるため負荷が大きい カウンタはオブジェクト毎に持つためコピーオンライトとの相性が悪い また言語の機能として実装されなければ明示的に行う必要がある(例えばCとか) そのためgcない言語ではマークスイープと比べ非常に面倒なことになる
- 410 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 10:35:48.15 ID:GKwGPSgf.net]
- androidで原因不明のフリーズが発生、プロジェクトはデスマーチに突入した
これだからGCは
- 411 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 11:39:27.66 ID:drxQ1xsy.net]
- これだからGCに頼りきった未熟者は
- 412 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 11:39:40.83 ID:MgEq8J/o.net]
- >>401
そりゃどんなものだって多少の負荷は有るよ しかし参照カウンタの上げ下げの負荷なんか マークスイープに比べれば無いも同然
- 413 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 18:02:09.56 ID:2IjmMYr5.net]
- マルチスレッド環境だと参照カウンタとかいうクソアルゴリズムは使い物にならない
- 414 名前:デフォルトの名無しさん mailto:sage [2016/03/26(土) 18:52:26.07 ID:QL60ocAy.net]
- 参照カウンタがオーバーフローしたらどうなんの?
- 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]
- 自慢になってないような
|

|