競馬鹿ねっと
|
| |
|
since 2000.1.1〜
|
|
|
|
http://www.keibaka.net
|
|
メールはアイコンをクリック!
|
|
|
|
競馬
|
|
┣
|
|
┣
|
|
┗
|
|
★
|
|
★
|
|
| |
|
Developer
|
|
◆
|
|
◆
|
|
◆ 08/06/01
|
|
|
◆
|
|
┣
|
|
┣
|
|
┣
|
|
┃┣
|
|
┃┗
|
|
|
◆ オープンソース
|
|
┣
|
|
┃┗
|
|
┗
|
|
|
◆
|
| |
|
その他
|
|
◆ 06/05/10
|
|
◆ 06/04/04
|
| |
|
PC
|
|
◆
|
| |
|
ウォッチリンク
|
|
◆
|
|
◆
|
|
利用させて頂いた順に並んでいます。
|
|
|
競馬鹿ねっとはXREAを利用して運営されています。
|
|
|
Yuko's Gallery様のフリー画像を利用させて頂いてます。
|
|
|
Aomusi'sWorld様のフリー画像を利用させて頂いてます。
|
|
|
|
PHPのガベージコレクタ
|
最終更新日:2005.12.17
|
|
| |
PHPでは一応ガベージコレクタを搭載しています。
このガベージコレクタ、どこまで信用して良いのやら???
ガベージコレクタさえあれば全てのメモリを回収してくれるという、間違った?知識を有したプログラマも多いのでちょっと考えてみたいと思います。
と言っても、私が勝手に想像するだけで正しい解釈とは限りませんがw
|
| |
Javaと.NETとPHP、全てガベージコレクタが搭載されていますが、一体何が違うのでしょうか?
そんな事、私も知りませんw
ガベージコレクタという言葉の定義は同じでも実装方法もそれぞれ違うでしょうし、説明できる人がいたら凄いです(◎_◎;)
後発の言語の方が優秀な仕組みになっているのは当然の事ですが、.NET(C#?)はJavaの欠点を踏襲した機能を提供しています。
Idisposeableインターフェースによる、リソース回収を明示的に実行する機能?です。
重要なのは回収タイミングがガベージコレクタ任せで無いのに明示的にリソース回収メソッドをCallする必要が無いって事ですかね?(c#のusing)
それともファイナライザを意図したタイミングで実行→System.GC.SuppressFinalize()でファイナライズ不要通知という事が可能な点が重要?
http://www.microsoft.com/japan/msdn/net/general/dotnetgcbasics.asp
何故.NETではリソースを回収するインターフェースを提供する必要があったのか?
さらに後発のPHPではどういった実装方法を選択しているのでしょうか?
ちょっと考えてみましょう!
|
| |
マネージ『manage』・・・管理する、処理する
つまりガベージコレクタの管理下にあるリソースと管理外のリソースが存在する訳ですね。
.NETの説明ページ
アンマネージ リソースの最も一般的な種類は、ファイル、ウィンドウ、ネットワーク接続などのオペレーティング システム リソースをラップしたオブジェクトです。
う〜ん、さすが.NETの説明なのでウィンドウなんて物が記載されていますが、OSの提供する低レベルAPIはヤバげだって事が想像できます。
Javaに比べると.NETでは直接APIをCall出来るなど、アンマネージドリソースを意識する機会は多そうです。
ポイント:ガベージコレクタが回収しないリソースは手動で開放する必要がある!
では、アンマネージドリソースを開放する方法について考えてみます。
|
| |
Java、.NETに共通して(というか真似して)ガベージコレクタがオブジェクトを回収する際にCallするメソッドがファイナライザです
アンマネージドリソースを使用するオブジェクトはファイナライザに明示的な開放ロジックを記述する事でリソースの開放を保証します。
class hogeClass {
protected void finalize() throws Throwable {
hoge.close();
}
}
ここで問題となるポイント
ファイナライザが呼び出されるタイミングはガベージコレクタ任せである。
長期的にシステムリソースなんていうOS管理下のヤバげなメモリを占有する事がしばしばある。
マズイじゃん!って事でファイナライザに記述する明示的なリソース開放をプログラマは意識して(オブジェクトが不要になった時点で実行するなど)記述する必要があります。
try {} finally { hoge.close(); }
ここで一つの疑問が生まれますよね?
あれ?Javaと.Netにあるファイナライザの概念ってPHPにありましたっけ?
実はPHP4の時からずっと考えていたテーマだったりしますw
|
| |
PHP5のオブジェクトではファイナライザでは無く、デストラクタを実装する事を選択しています。
.NETで提供されたIdisposeableインターフェースに対するもう一つの回答と言う事になるのでしょうか?
PHPにはファイナライザという言葉の概念がなさそうなので、ここで使用する言葉の定義を明確にしておくと・・・。
ファイナライザ・・・ガベージコレクタから見たオブジェクトの破棄処理
デストラクタ・・・スクリプトから見たオブジェクトの破棄処理
PHPでは、静的ライブラリを組み込んでコンパイルする事で、様々な機能を利用する事ができますが開放ロジックを強要する記述を見た事がありません。
この事から静的ライブラリを組み込んでコンパイルする時に、内部的にファイナライザを生成している事が想像できます。
少し調べてみると、register_list_destructorsという関数で、ガベージコレクタにファイナライザ(デストラクタハンドラ)を登録しているっぽいです。
http://www.php.net/manual/ja/zend.variables.resource.php
つまり、PHPでは関数レベルで提供されているリソースに関しては全てマネージドリソースだと考えられます。
http://www.php.net/manual/ja/resource.php
スクリプト中で↑のリソース型の一覧にあるリソース開放関数を記述し忘れても、内部で自動生成されているファイナライザで後始末する形で機能を提供するのがPHPの流儀である事が想像できます。
.NETのWindowsプログラミングの場合はCOMやDLLといった既存資産の再利用から離れる事が難しい為、アンマネージドリソースという概念が無くなる事は無いでしょう。
じゃあ、Javaは何でPHPと同じような実装ではないか不思議になりますが謎は謎のままに・・・。
おぉ?内部的な事を何も考えれないプログラマがますます増えそうですが、それが目的ですからぁ〜。
PHPって結構凄いんじゃん?って結論に至りましたがどうなんでしょうか?(´へ`;)
ポイント
結局、open←→closeのような対になる関数がある場合は明示的な開放を記述すべき
でも記述忘れてもPHP側でリソース開放は担保しているので気にしない人は(・ε・)キニシナイ!!
PHPでもWindows上でCOMを使うと.netと同様にopen←→closeしないとダメポ!!
取得したリソースの先でopen←→closeを伴うものは、確実にアンマネージドなリソースが消費されてます。
excel,word,adoなどなど・・・PHPでそんなの使うのか?って感じですがw
JavaからCOMを使えるのかは知りませんが、使えるなら当然同じでしょう。
|
| |
| Java |
.NET(C#?) |
PHP |
|
ファイナライザ
|
○
|
○
|
×
|
|
デストラクタ
|
×
|
×
|
○
|
|
明示的ファイナリゼーション
|
| × |
○ |
△・・・unsetの挙動が不明 |
|
ガベージコレクタに任せないリソース明示的開放
|
finaliza()にも一応リソース開放を記述した上で
try {} finally { hoge.close(); }
|
dispose()にリソース開放を記述した上で
try {} finally { hoge.close(); }
|
finally節は不要?なので実装されていない
|
|
|
dispose()にリソース開放を記述した上で
using {}
using節を離れた時点でdispose()が呼び出される
|
__destruct()にリソース開放を記述した上で
そのオブジェクトが不要になった時点でデストラクタが動作する
|
|
となると誰が明示的開放を意識しなければいけないか?
|
| オブジェクトを利用するプログラマ |
オブジェクトを利用するプログラマ (結局明示的なusingという記述が必要) |
オブジェクトを設計・作成するプログラマ (利用者は何も考えずにデストラクタで破棄) |
こうして見比べるとPHPは関数ベースなので、ちょっと扱いが違うような?
例えばファイルを扱うオブジェクトを自分で作成した上でならfinally節は不要でデストラクタ任せで良いじゃん!となりますが、
(というかそうしたいからPHP4でデストラクタを実装する要望が高かったのでは?)
fopenで取得したハンドルを自力でfcloseするコーディングが必要なパターンもあるのかなと???
どういう比較をするのが正しいのかは微妙ですが、オブジェクト指向って事で深くは追求しないでw
|
|