アカウント名:
パスワード:
malloc/freeの処理コストってどれくらいかかるんだろう。メモリがバカ高かった時代はmalloc/freeで使用量を厳密に、というのはわかるんだが、ンGB当たり前の昨今、malloc/freeの処理コストの方が高くなったりしないのかな?と。「だいたい、こんくらいとっといてぇー」というようなプログラミングスタイルは無いのだろうか、と思う。
・・・malloc/free叩いとらんな、最近。
>malloc/freeの処理コストの方が高くなったりしないのかな?>と。「だいたい、こんくらいとっといてぇー」というようなプログラミングスタイルは無いのだろうか、と思う。
チマチマ何回かに分けて取るより一回にまとめて取った方が相対的に安くなるので、「だいたい、このくらい」でまとめて取ってから、それをアプリ内部でチマチマ切り刻んで使うというテクニックは昔からあったと思います。
そしてJVMなんかだと、それを自動でやってくれるので、Javaな人にとってはこれも「もうやらなくていい昔のコーディングテクニック」の一つですね。
それから、OSが仮想記憶をサポートして以降は、mallocは実メモリを確保するわけではなくOSの管理テーブルに予約するだけなので、ちょっとくらい大きい領域を予約しても影響はすごく小さくなってるはずです。
>そうか、Javaだと(よほど変なことをしない限り)メモリリーク心配しなくていいのか(本当?)
いえいえ、お馬鹿なコードを書くとリークしていきますよ。使わなくなったオブジェクトに対する参照をつかんだままにしてればいくらでもメモリ使用量は増えていきますから。
スコープを外れた変数のつかんでるオブジェクトの回収とかは勝手にやってくれますが変数参照が生き残っていれば回収できないのです。プログラムグローバルなキャッシュを何も考えずに書かせると、そんなコードができるんじゃないですかね。ただ、まぁ、そうはいってもCに比べれば格段に問題のあるコードは書きにくくなっているでしょうね。
>>そうか、Javaだと(よほど変なことをしない限り)メモリリーク心配しなくていいのか(本当?)>いえいえ、お馬鹿なコードを書くとリークしていきますよ。
「メモリリーク」という単語を、「ポインタ(或いは参照)を全て手放したにもかかわらず、領域の解放(free)を 忘れたために、メモリを少しずつ食い尽くしていく現象」と定義するなら、Javaだと「メモリリーク」の心配はほぼありません。#まさに「よほど変なことをしない限り」、且つ「VMやフレームワークにバグがない限り」。#C言語で長期間動作するアプリを作るのが難しいのは、このような「狭義の#メモリリーク」の検出とデバッグが難しいからで、Javaではそれが発生しない#ことがサーバー向けアプリに適している理由でもあります。
少なくとも昔は「メモリリーク」というのはそういう意味で使われているものだと思っていましたが、最近では参照を掴んだまま離さない「到達可能なオブジェクト」=「(GC的に)生きているオブジェクト」が生き残っているのも「メモリリーク」だと呼ぶ人はいます。そういう「広義のメモリリーク」ならばJavaでも起こりえます。#これはGCの基本的な特性なので、おそらく他のGCを持つ言語でも同じになる。
でもこれは言うまでもなくC言語でも他の言語でも起こることですね。そういうコードしか書けない人は、いずれにせよC言語で長期間安定動作するようなコードは書けないので、Javaにおける広義のメモリリークの心配をするには十年早いかと。
御指摘の通り、長期運用を考慮していないという意味で問題だと思います。
ただ、Javaに限定した場合、最大メモリ使用量が予め設定されているので、(その範囲を超えないという意味で)OS側への影響は与えにくいですね。JVMで確保したメモリ内で段々と空き領域が減っていく・・・という話になります。
# 個人的にはOS上のメモリ使用量しか見てない運用者というのがいて、# JVM内のメモリ使用量を把握していない例が多いのが頭痛の種。(T-T
>運用者にとっては区別する意味が全くない。>この話を聞いて私が思い出す言葉は「五十歩百歩」です。プログラミングが分かってない人の意見かな。
運用者にとっては違わないかもしれないけど、開発者にとっては全然違いますよ。
狭義のメモリリークはデバッグが凄く難しい。それに比べ広義のメモリリークは対応が遥かに容易。
結果として、開発に同じだけのリソースを割り振った場合に、Cで作った場合は開発期間が長期化しメモリリークが多く不安定で、Javaで作った場合は短い開発期間でもメモリリークが少なく安定する、という違いとなって現れることが多い。
もちろん無限の開発コストと無限の開発期間がつぎ込める場合はこの限りではありません。
結果を区別する必要は無いけど、原因を区別する必要は有るね。
区別する気が無い人なら運用者にもならないで欲しい。なぜならその人は、バグったときにその区別ができるような情報をデバッグ者に渡す「気」が無いわけでしょ?
そういうところで情報断絶をおこしてデバッグが立ち往生すること、実際凄く多いんだよorzつまりそういう場合にバグがいつまでたっても直らないのはハッキリいってそいつのせい。
全く気にする必要が無い人はそれはエンドユーザというんだよ。運用者じゃない。
運用者は開発者とともに原因と結果の界面に居る人だ(でないと困る)。両方に目配りをしてもらいたい。
>>運用者にとっては区別する意味が全くない。>>この話を聞いて私が思い出す言葉は「五十歩百歩」です。>プログラミングが分かってない人の意見かな。
>運用者にとっては違わないかもしれないけど、開発者にとっては全然違いますよ。
>狭義のメモリリークはデバッグが凄く難しい。>それに比べ広義のメモリリークは対応が遥かに容易。
狭義/広義と使い分けているが、ただ単にスキル不足な気がする。昔ならいざ知らず、統合開発環境が主流な現在においてはどちらも容易。(ブレークポイント張りまくれるでしょ。スタックの中身ですら見えるでしょ。)プログラミングが分かってない人の意見かな。<
>昔ならいざ知らず、統合開発環境が主流な現在においてはどちらも容易。>(ブレークポイント張りまくれるでしょ。スタックの中身ですら見えるでしょ。)
ブレークポイントはどこで何が発生するか分かってないと張っても無駄です。
(狭義の)メモリリークの難しい点は、それを発生させる条件を特定することや、或いはそもそもメモリリークの有無を知ることそのものなんですよ。どういう条件の時にメモリリークが発生するのかまで特定できていれば、その部分のバグについては8割方片付いたも同じです。
ブレークポイントはその残りの2割のさらに一部を楽にできる程度の効果しかありません。#そもそも統合開発環境がある前からデバッガなんてありましたよ。#ブレークポイントをはったりもやってた。でも(狭義の)メモリリークは#最も面倒なバグの一つとして有名だったのです。
>出来ない君集団にやらせるなら、何使わせても一緒じゃね!?この部分についてだけは同意。
> でもこれは言うまでもなくC言語でも他の言語でも起こることですね。そういう> コードしか書けない人は、いずれにせよC言語で長期間安定動作するようなコードは> 書けないので、Javaにおける広義のメモリリークの心配をするには十年早いかと。おかしくね?Javaにおける広義のメモリリークを起こすようなコードを書く人はその心配をしたほうがいいんでは・・・?
>#まさに「よほど変なことをしない限り」、且つ「VMやフレームワークにバグがない限り」。>#C言語で長期間動作するアプリを作るのが難しいのは、このような「狭義の>#メモリリーク」の検出とデバッグが難しいからで、Javaではそれが発生しない>#ことがサーバー向けアプリに適している理由でもあります。
これ、素直に初耳なんですけど。。サーバ向けアプリで知っているとすれば、銀行勘定系(COBOL)のフロントUI位なんですが、そんなに、サーバー向けアプリ+Javaって多い!?また、開発言語の選択基準がメモリの確保/解放が決め手になるなんて、どんだけ幼稚なんだと
>サーバ向けアプリで知っているとすれば、銀行勘定系(COBOL)のフロントUI位なんですが、>そんなに、サーバー向けアプリ+Javaって多い!?
むしろ日本の銀行だけが未だにCOBOLとかを使っているガラパゴスで、外資系金融機関などはのきなみJavaへのリプレースが済んでるそうですよ。
Googleも元は90年代に作られたのでC言語だったけど、とっくにJavaを使う方向に変更されてるし。
>また、開発言語の選択基準がメモリの確保/解放が決め手になるなんて、どんだけ幼稚なんだと。。これは「大間違い」です。
Javaがサーバーサイドで利用される理由は、マルチスレッドとの親和性、豊富なライブラリ、パフォーマンス、高い生産性など、それらの総合評価によるものです。決してGCが「決めて」になったわけではありません。
しかし、もしそれらのメリットがあったとしても、もしメモリリークを引き起こしやすい言語であれば、これほどまでに利用されることはなかったかもしれません。それくらいメモリリークはサーバーサイドでは厄介な問題と言えるのです。
>メモリの解放忘れをメモリリークと呼ぶのも問題無いと思うが?いえ、「解放を忘れてる」のだけではなく「動いている」のです。
#車で言えば、「赤信号で停車している」のではなく、#「アクセルを踏んだままにしている」くらいの差がある。#アクセルを踏んだままなので、エンジンを止めるわけにはいかないのです。
これ、素直に初耳なんですけど。。サーバ向けアプリで知っているとすれば、銀行勘定系(COBOL)のフロントUI位なんですが、そんなに、サーバー向けアプリ+Javaって多い!?
一時期、DBを叩くWEBアプリをTomcatのようなJavaフレームワークで構築するのが流行りましたよ。今時はマシンパワーが上がったのでPerlやPHPやRubyを使うようになりましたけど。
また、開発言語の選択基準がメモリの確保/解放が決め手になるなんて、どんだけ幼稚なんだと。。<確かにそんな話する、トンでも外注(害虫!?)もいることにはいるけどなぁ。。
既出っぽいですけどメモリアロケーションの実体が言語インタプリタにあると言うのはメンテナンスの面からはやりやすいのですが。コンパイラでネイティブコードにした物を動かした場合のこの手のバグ潰しのややこしさを考えると…
まぁ、純粋にCだけで書いて必要なメモリは必ずmalloc噛ます。構造体すら一度mallocして割り当ててしまう。とかそういう非常に神経質にやる場合は例外として、下手なC++コンパイラとかみたくオブジェクトバンバン作って後で変な残りカスが出てしまうというのはどこにバグの責任所在があるか見極めるのが非常に難しい。特に多くのプロセスが立ち上がったり消えたりを繰り返す場合には見えないメモリリークの蓄積で仮想記憶領域を食いつぶし、マシン飛ばしたり速度落としたりとか普通にありますよ。# MPU自体が完璧に近いガベージコレクション機能を持てばC++も信頼出来るようになるのですが、# 今はOSカーネルのGC機能とコンパイラの正確さ頼みだからな…
動的メモリを確保できる言語は、メモリリークの問題を常に持っている。この位の事を理解していないと、言語の種類なんか関係なくロクなコードなんか書けないと思けど。
このあたりは[全体|詳細]設計とか誰にどこのコーディング振るかというプロジェクトマネージメントとかの問題でコーディングに入る前に理詰めで潰せていないとどうしょうもないですよ。それでもコーディングに入ったら最初はリークバリバリになりがちで、それが書き方の問題か組み合わせの問題か容易に見分けられる準備していないと。一つ一つのルーチンがメモリリーク潰せていても、組み合わせた場合にどうかというのはまた違う。設計段階でメモリリーク誘発しにくいように見極めが出来ていないとダメなのでは。
少なくとも Visual C++ では、メモリーを確保して解放しないことを「メモリーリーク [microsoft.com]」と呼んでいます。日本語版のドキュメントでは「メモリ リークとは、割り当て済みのメモリを正しく解放できない状態を指します」と、わかったようなわからないような説明になっているので、英語版 [microsoft.com]から引用します。
One of the most subtle and hard-to-detect bugs is the memory leak―the failure to properly deallocate memory that was previously allocated.(訳: 最も微妙で最も見つけにくいバグの一つがメモリーリーク、すなわち確保したメモリーを正しく解放しないことである。)
One of the most subtle and hard-to-detect bugs is the memory leak―the failure to properly deallocate memory that was previously allocated.
(訳: 最も微妙で最も見つけにくいバグの一つがメモリーリーク、すなわち確保したメモリーを正しく解放しないことである。)
failureとあるので、(プログラマがメモリを解放しようとしたにもかかわらず)失敗した、というニュアンスでしょう。
failure は「何かをしようとして失敗すること」とは限りません (例 [alc.co.jp])。とはいうものの、おっしゃる通り、「failure to deallocate」という英語の解釈としては「プログラマーはメモリーを解放しようとしているにもかかわらず (何らかの理由で) 解放に失敗すること」というのもありえますね。メモリーリークというのはそういう意味ではないと思っていますが、証拠を挙げるのは僕には難しいです。
え?Javaでもマルチスレッド処理なんかでは一見GCにより開放されると思われる箇所でもメモリーリークを起こしますよ。中規模以上のプロジェクトで2~3件の頻度ですが...
もしかしてConservative GCのことを語っている?
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
吾輩はリファレンスである。名前はまだ無い -- perlの中の人
時々思うんだが (スコア:3, 興味深い)
malloc/freeの処理コストってどれくらいかかるんだろう。メモリがバカ高かった時代はmalloc/freeで使用量を厳密に、というのはわかるんだが、ンGB当たり前の昨今、malloc/freeの処理コストの方が高くなったりしないのかな?と。「だいたい、こんくらいとっといてぇー」というようなプログラミングスタイルは無いのだろうか、と思う。
・・・malloc/free叩いとらんな、最近。
-- gonta --
"May Macintosh be with you"
Re: (スコア:2, 興味深い)
>malloc/freeの処理コストの方が高くなったりしないのかな?
>と。「だいたい、こんくらいとっといてぇー」というようなプログラミングスタイルは無いのだろうか、と思う。
チマチマ何回かに分けて取るより一回にまとめて取った方が相対的に安くなる
ので、「だいたい、このくらい」でまとめて取ってから、それをアプリ内部で
チマチマ切り刻んで使うというテクニックは昔からあったと思います。
そしてJVMなんかだと、それを自動でやってくれるので、Javaな人にとっては
これも「もうやらなくていい昔のコーディングテクニック」の一つですね。
それから、OSが仮想記憶をサポートして以降は、mallocは実メモリを確保する
わけではなくOSの管理テーブルに予約するだけなので、ちょっとくらい大きい
領域を予約しても影響はすごく小さくなってるはずです。
Re: (スコア:0)
そうか、Javaだと(よほど変なことをしない限り)メモリリーク心配しなくていいのか(本当?)でも起動時に1GByte以上のヒープサイズが必要ですとかいわれると、いくらメモリ安くなったとっていってもすこしひくなぁ。
Re: (スコア:1)
>そうか、Javaだと(よほど変なことをしない限り)メモリリーク心配しなくていいのか(本当?)
いえいえ、お馬鹿なコードを書くとリークしていきますよ。
使わなくなったオブジェクトに対する参照をつかんだままにしてれば
いくらでもメモリ使用量は増えていきますから。
スコープを外れた変数のつかんでるオブジェクトの回収とかは勝手にやってくれますが
変数参照が生き残っていれば回収できないのです。
プログラムグローバルなキャッシュを何も考えずに書かせると、そんなコードができるんじゃないですかね。
ただ、まぁ、そうはいってもCに比べれば格段に問題のあるコードは書きにくくなっているでしょうね。
Re:時々思うんだが (スコア:2, 参考になる)
>>そうか、Javaだと(よほど変なことをしない限り)メモリリーク心配しなくていいのか(本当?)
>いえいえ、お馬鹿なコードを書くとリークしていきますよ。
「メモリリーク」という単語を、
「ポインタ(或いは参照)を全て手放したにもかかわらず、領域の解放(free)を
忘れたために、メモリを少しずつ食い尽くしていく現象」
と定義するなら、Javaだと「メモリリーク」の心配はほぼありません。
#まさに「よほど変なことをしない限り」、且つ「VMやフレームワークにバグがない限り」。
#C言語で長期間動作するアプリを作るのが難しいのは、このような「狭義の
#メモリリーク」の検出とデバッグが難しいからで、Javaではそれが発生しない
#ことがサーバー向けアプリに適している理由でもあります。
少なくとも昔は「メモリリーク」というのはそういう意味で使われているものだと
思っていましたが、最近では参照を掴んだまま離さない
「到達可能なオブジェクト」=「(GC的に)生きているオブジェクト」
が生き残っているのも「メモリリーク」だと呼ぶ人はいます。
そういう「広義のメモリリーク」ならばJavaでも起こりえます。
#これはGCの基本的な特性なので、おそらく他のGCを持つ言語でも同じになる。
でもこれは言うまでもなくC言語でも他の言語でも起こることですね。そういう
コードしか書けない人は、いずれにせよC言語で長期間安定動作するようなコードは
書けないので、Javaにおける広義のメモリリークの心配をするには十年早いかと。
Re:時々思うんだが (スコア:3, 参考になる)
言葉の定義がどうであろうと起きている現象がなんであろうと
問題ですね。
このメモリリークの広義/狭義(あるいはメモリリーク/メモリリテンション)って
のは良く聞く話なのだけど運用者にとっては区別する意味が全くない。
この話を聞いて私が思い出す言葉は「五十歩百歩」です。
Re:時々思うんだが (スコア:1)
御指摘の通り、長期運用を考慮していないという意味で問題だと思います。
ただ、Javaに限定した場合、最大メモリ使用量が予め設定されているので、
(その範囲を超えないという意味で)OS側への影響は与えにくいですね。
JVMで確保したメモリ内で段々と空き領域が減っていく・・・という話になります。
# 個人的にはOS上のメモリ使用量しか見てない運用者というのがいて、
# JVM内のメモリ使用量を把握していない例が多いのが頭痛の種。(T-T
Re:時々思うんだが (スコア:1)
>運用者にとっては区別する意味が全くない。
>この話を聞いて私が思い出す言葉は「五十歩百歩」です。
プログラミングが分かってない人の意見かな。
運用者にとっては違わないかもしれないけど、開発者にとっては全然違いますよ。
狭義のメモリリークはデバッグが凄く難しい。
それに比べ広義のメモリリークは対応が遥かに容易。
結果として、開発に同じだけのリソースを割り振った場合に、
Cで作った場合は開発期間が長期化しメモリリークが多く不安定で、
Javaで作った場合は短い開発期間でもメモリリークが少なく安定する、
という違いとなって現れることが多い。
もちろん無限の開発コストと無限の開発期間がつぎ込める場合はこの限りではありません。
Re: (スコア:0)
結果を区別する必要は無いけど、
原因を区別する必要は有るね。
区別する気が無い人なら運用者にもならないで欲しい。
なぜならその人は、バグったときにその区別ができるような情報をデバッグ者に渡す「気」が無いわけでしょ?
そういうところで情報断絶をおこしてデバッグが立ち往生すること、実際凄く多いんだよorz
つまりそういう場合にバグがいつまでたっても直らないのはハッキリいってそいつのせい。
全く気にする必要が無い人はそれはエンドユーザというんだよ。運用者じゃない。
運用者は開発者とともに
原因と結果の界面に居る人だ(でないと困る)。両方に目配りをしてもらいたい。
Re: (スコア:0, フレームのもと)
>>運用者にとっては区別する意味が全くない。
>>この話を聞いて私が思い出す言葉は「五十歩百歩」です。
>プログラミングが分かってない人の意見かな。
>運用者にとっては違わないかもしれないけど、開発者にとっては全然違いますよ。
>狭義のメモリリークはデバッグが凄く難しい。
>それに比べ広義のメモリリークは対応が遥かに容易。
狭義/広義と使い分けているが、ただ単にスキル不足な気がする。
昔ならいざ知らず、統合開発環境が主流な現在においてはどちらも容易。
(ブレークポイント張りまくれるでしょ。スタックの中身ですら見えるでしょ。)
プログラミングが分かってない人の意見かな。<
Re:時々思うんだが (スコア:3, 参考になる)
>昔ならいざ知らず、統合開発環境が主流な現在においてはどちらも容易。
>(ブレークポイント張りまくれるでしょ。スタックの中身ですら見えるでしょ。)
ブレークポイントはどこで何が発生するか分かってないと張っても無駄です。
(狭義の)メモリリークの難しい点は、それを発生させる条件を特定することや、
或いはそもそもメモリリークの有無を知ることそのものなんですよ。どういう
条件の時にメモリリークが発生するのかまで特定できていれば、その部分のバグに
ついては8割方片付いたも同じです。
ブレークポイントはその残りの2割のさらに一部を楽にできる程度の効果しかありません。
#そもそも統合開発環境がある前からデバッガなんてありましたよ。
#ブレークポイントをはったりもやってた。でも(狭義の)メモリリークは
#最も面倒なバグの一つとして有名だったのです。
>出来ない君集団にやらせるなら、何使わせても一緒じゃね!?
この部分についてだけは同意。
Re: (スコア:0)
> でもこれは言うまでもなくC言語でも他の言語でも起こることですね。そういう
> コードしか書けない人は、いずれにせよC言語で長期間安定動作するようなコードは
> 書けないので、Javaにおける広義のメモリリークの心配をするには十年早いかと。
おかしくね?
Javaにおける広義のメモリリークを起こすようなコードを書く人は
その心配をしたほうがいいんでは・・・?
Re: (スコア:0)
>#まさに「よほど変なことをしない限り」、且つ「VMやフレームワークにバグがない限り」。
>#C言語で長期間動作するアプリを作るのが難しいのは、このような「狭義の
>#メモリリーク」の検出とデバッグが難しいからで、Javaではそれが発生しない
>#ことがサーバー向けアプリに適している理由でもあります。
これ、素直に初耳なんですけど。。
サーバ向けアプリで知っているとすれば、銀行勘定系(COBOL)のフロントUI位なんですが、
そんなに、サーバー向けアプリ+Javaって多い!?
また、開発言語の選択基準がメモリの確保/解放が決め手になるなんて、どんだけ幼稚なんだと
Re:時々思うんだが (スコア:2, 興味深い)
・言語としてのシェアがトップクラス
・Javaをクライアントサイドで使うことは少ない(携帯Javaはそこそこ多いけど)
ということを考えると、かなり多いのでは?
> 動的メモリを確保できる言語は、メモリリークの問題を常に持っている。
一見、動的メモリ確保をしていないように見えても、メモリリークすることがあります。
g++2.9.5(だったかな)で例外をcatchするとスタックが本来の位置より数bytesせり上がるというバグがあって、長期間動かすと徐々にプロセスのメモリ使用量が増えていくという現象に出くわしました。あれは怖かった。
Re:時々思うんだが (スコア:1)
>サーバ向けアプリで知っているとすれば、銀行勘定系(COBOL)のフロントUI位なんですが、
>そんなに、サーバー向けアプリ+Javaって多い!?
むしろ日本の銀行だけが未だにCOBOLとかを使っているガラパゴスで、
外資系金融機関などはのきなみJavaへのリプレースが済んでるそうですよ。
Googleも元は90年代に作られたのでC言語だったけど、とっくにJavaを使う
方向に変更されてるし。
>また、開発言語の選択基準がメモリの確保/解放が決め手になるなんて、どんだけ幼稚なんだと。。
これは「大間違い」です。
Javaがサーバーサイドで利用される理由は、マルチスレッドとの親和性、
豊富なライブラリ、パフォーマンス、高い生産性など、それらの総合評価
によるものです。決してGCが「決めて」になったわけではありません。
しかし、もしそれらのメリットがあったとしても、もしメモリリークを引き起こし
やすい言語であれば、これほどまでに利用されることはなかったかもしれません。
それくらいメモリリークはサーバーサイドでは厄介な問題と言えるのです。
>メモリの解放忘れをメモリリークと呼ぶのも問題無いと思うが?
いえ、「解放を忘れてる」のだけではなく「動いている」のです。
#車で言えば、「赤信号で停車している」のではなく、
#「アクセルを踏んだままにしている」くらいの差がある。
#アクセルを踏んだままなので、エンジンを止めるわけにはいかないのです。
設計者の問題(Re:時々思うんだが (スコア:1)
一時期、DBを叩くWEBアプリをTomcatのようなJavaフレームワークで構築するのが流行りましたよ。
今時はマシンパワーが上がったのでPerlやPHPやRubyを使うようになりましたけど。
既出っぽいですけどメモリアロケーションの実体が言語インタプリタにあると言うのはメンテナンスの面からはやりやすいのですが。コンパイラでネイティブコードにした物を動かした場合のこの手のバグ潰しのややこしさを考えると…
まぁ、純粋にCだけで書いて必要なメモリは必ずmalloc噛ます。構造体すら一度mallocして割り当ててしまう。とかそういう非常に神経質にやる場合は例外として、下手なC++コンパイラとかみたくオブジェクトバンバン作って後で変な残りカスが出てしまうというのはどこにバグの責任所在があるか見極めるのが非常に難しい。
特に多くのプロセスが立ち上がったり消えたりを繰り返す場合には見えないメモリリークの蓄積で仮想記憶領域を食いつぶし、マシン飛ばしたり速度落としたりとか普通にありますよ。
# MPU自体が完璧に近いガベージコレクション機能を持てばC++も信頼出来るようになるのですが、
# 今はOSカーネルのGC機能とコンパイラの正確さ頼みだからな…
このあたりは[全体|詳細]設計とか誰にどこのコーディング振るかというプロジェクトマネージメントとかの問題でコーディングに入る前に理詰めで潰せていないとどうしょうもないですよ。それでもコーディングに入ったら最初はリークバリバリになりがちで、それが書き方の問題か組み合わせの問題か容易に見分けられる準備していないと。
一つ一つのルーチンがメモリリーク潰せていても、組み合わせた場合にどうかというのはまた違う。
設計段階でメモリリーク誘発しにくいように見極めが出来ていないとダメなのでは。
Re: (スコア:0)
Re: (スコア:0)
フラグメンテーションが起きるのは結果です。
たとえば、256KBの領域があるとき、100KB、1KBと確保して、100KBを解放すると、100KB+155KBの2つになります。後から200KBを確保できません。
その1KBがリークしていたら、もう200KBを確保できることはありませんが、1KBが解放されれば200KBを確保できることがあるかもしれません。
しかし、実際の問題としては必要な時に必要なメモリを確保できなければ、実行できません。
Win32アプリなんか、ちょっとスレッドを動かすと、スレッド用スタックでメモリが分断されて、256MBを超えるメモリは1つくらいしか確保できません。実際使い物にならないけど、これをメモリリークとは言わないし、言語Cとは限らない。
Re: (スコア:0)
しかしJavaなどGCのある言語では、かような場合でも自動的にコンパクションを行いますから、Cよりも本質的な部分で楽でしょう。
Cなどでは適切な順序でメモリの解放を行わないとフラグメンテーションを起こしてしてしまいますし、これが大変やっかいなバグとなることは周知のとおりです。
(フラグメンテーションがメモリリークを引き起こす、とでも言いましょうか)
メモリの解放忘れというのはごく初歩的なミスですから、メモリリークなどという大層な呼び名を頂いているとは思わなかったということです。
ただのメモリの解放忘れが引き起こす現象もメモリリークと呼ぶということであれば、認識を改めます。
Re: (スコア:0)
メモリをたくさん使いたいなら、DLLのロードアドレスやスタックの置かれる場所やサイズを、自分で指定しなきゃ。
メモリーリーク (スコア:2)
少なくとも Visual C++ では、メモリーを確保して解放しないことを「メモリーリーク [microsoft.com]」と呼んでいます。日本語版のドキュメントでは「メモリ リークとは、割り当て済みのメモリを正しく解放できない状態を指します」と、わかったようなわからないような説明になっているので、英語版 [microsoft.com]から引用します。
Re: (スコア:0)
Re:メモリーリーク (スコア:2)
failure は「何かをしようとして失敗すること」とは限りません (例 [alc.co.jp])。とはいうものの、おっしゃる通り、「failure to deallocate」という英語の解釈としては「プログラマーはメモリーを解放しようとしているにもかかわらず (何らかの理由で) 解放に失敗すること」というのもありえますね。メモリーリークというのはそういう意味ではないと思っていますが、証拠を挙げるのは僕には難しいです。
Re: (スコア:0)
具体的に、どんなOSで?
WindowsやLinuxでは、mallocやnewしたものをfree、deleteし漏らしてメモリリークしても、プロセスが終了したときには、当該のプロセスがプライベートに確保したメモリはすべて開放されますよ。
Re: (スコア:0)
もし知っていたら、後学のために教えてください。
_beginthreadex()でもCreateThread()でもスタックの開始アドレスは指定できませんが、どのようにすれば、スタックのアドレスを指定できるのでしょうか?
また、MFCなどがIEコンポーネントを使ったり、ウインドウを開いたりして、内部で使ったメモリの位置を指定したり、解放する方法も知っていたら、教えてほしいです。
64bit OSが一般的になれば、"昔のコーディングテクニック"の仲間入りですが、まだ使えるので、可能ならば知りたいです。
Re: (スコア:0)
連続したアドレス空間が必要なら、早々にVirtualAllocで予約すべし。
Re: (スコア:0)
え?Javaでもマルチスレッド処理なんかでは一見GCにより開放されると思われる箇所でもメモリーリークを起こしますよ。
中規模以上のプロジェクトで2~3件の頻度ですが...
Re: (スコア:0)
もしかしてConservative GCのことを語っている?