Iteratorパターンはfor文じゃダメなの?

「Iteratorパターンなんて使わなくても、for文を使えば良いんじゃないの?」

煽りではなく、不意にそう思ってしまった。でも、冷静に考えると、このふたつは等価であるとは限らない。そして、反復処理をそのコレクション型クラス自体に隠蔽することに、大きな意味があるな、と思い直した。危ない、危ない。

List list = new SomeArrayClass();
for (Iterator it = list.iterator(); it.hasNext();) {
    System.out.println(it.next());
}

これを for文 で扱おうとすると、SomeArrayClass が何者かを知らないといけないので、オブジェクト間の関係が密になってしまう。その正体が何なのかを意識しなくて良いのが、iterator の良いところ。極端な例ではあるけど、これなら将来的に SomeArrayClass の内部実装が変わることに耐えられる。

そこに気付いたところで、次なる疑問。じゃあ、拡張for文とは何が違うのか。

List<String> list = new SomeArrayClass<String>();
for (String str : list) {
    System.out.println(str);
}

こう書くと、上のIteratorパターンのサンプルとまったく同じ役割を果たしてくれる。何が違うんだろうと思って探索した結果、どうやら拡張for文は内部で iterator を使っている模様。ああ、そういうことでしたか。

こういうことをキチンと踏まえた上で、敢えてIteratorパターンを用いず、for文で反復制御を書くことに意味があるんだろうなあ。

続きを読む "Iteratorパターンはfor文じゃダメなの?"

NetBeansのヒープサイズ調整

NetBeans でプロジェクトを構築しようとしたところ、OutOfMemoryError が出て、構築に失敗してしまった。ソースファイルが2000を超えたら、そりゃ厳しいか。

NetBeans 使用時のヒープサイズは、%NETBEANS_HOME%\etc\netbeans.conf にて設定できる。(%NETBEANS_HOME% は NetBeans のインストールディレクトリ)

# 6行目あたり(実際は1行)
netbeans_default_options="-J-Xms32m -J-Xmx128m -J-XX:PermSize=32m
 -J-XX:MaxPermSize=96m -J-Xverify:none -J-Dapple.laf.useScreenMenuBar=true"

今回は単純なメモリ不足が問題だったので、最大ヒープサイズを大きくするため、-J-Xmx を 256m に設定。これで無事、プロジェクトの構築が完了。ふう。

ちなみに、上記の起動オプションについてまとめると以下のとおり。

オプション説明
-J-Xms32m初期ヒープサイズ (この場合32MB)
-J-Xmx128m最大ヒープサイズ (この場合128MB)
-J-XX:PermSizeParmanent領域の初期メモリサイズ
-J-XX:MaxPermSizePermanent領域の最大メモリサイズ
-J-Xverify:noneJavaバイトコード検査を無効にして起動時間を短縮
-J-Dapple.laf.useScreenMenuBarSwingのスクリーンメニューバー使用フラグ

Tomcat5.5 で DataSource を使う

これまで eclipse で製造していたWebアプリケーションを、Profiler にかけるため、NetBeans に必死で移行。その結果、DataSource でコケる。

javax.servlet.ServletException:
Cannot create JDBC driver of class '' for connect URL 'null'

やっぱり設定をコピペするだけでは、動いてくれないらしい。ううう。

原因は Tomcat にあり。これまで Tomcat5.0 で開発していたのだけれども、NetBeans5.0 にバンドルされていたのは Tomcat5.5 だった。「0.5くらいなら大丈夫だべ」と思って強気で攻めたんだけど、だいぶ違うみたいでして。トム猫さん、頼むよ。

具体的には、JNDI リソースの指定方法が変わった。設定は、<ResourceParams> タグを使わず、<Resource> タグの属性として指定しなければいけなくなったようだ。

以下、設定のサンプル。

続きを読む "Tomcat5.5 で DataSource を使う"

NetBeans Profiler のインストール

Java のメモリリークを発見するために、NetBeans Profiler を使ってみることにした。JProbeBorland Optimizeitなどの商用ツールが一般的な、Javaパフォーマンスチューニングツールにあって、なんと無償。試しに使ってみるには良いんじゃないかと。

以下、使用までの流れ。

続きを読む "NetBeans Profiler のインストール"

java におけるメモリーリーク

メモリーリーク。記憶漏れで、あああああ、である。

厳しいスケジュールを乗り越え、ようやく本番稼動まで漕ぎつけたシステムが、今度は java.lang.OutOfMemoryError に見舞われた。試験環境では発生せず、本番になって起こるところが、何ともいじらしい。

原因のひとつは、使用ユーザー数が想定を超えたこと。もうひとつは、セッションに保持する情報が多いこと。…という線で話は収束しているけれども、想定の倍程度のユーザー数がちょっと触っただけでコケるというのは、大げさだろう。負荷テスト足りなかったけどさ。どっかに致命的なメモリーリークがある気がする。

いまだに Java には GC があるからメモリーリークが無いと思っている人がいるけど、そんなことはない。不要になったデータに参照が残っていれば、メモリが開放されず、メモリリークになりうる。たとえばWebアプリケーションでは、Servlet で 非static なクラス変数を使用すると、そのインスタンスは Servletコンテナが参照し続けるため、メモリリークになる可能性がある。

そんなわけで、チマチマと開発メンバの書いたソースを読んでいたら、眠くなってきた。こんなところで春を感じる。ソース量も膨大だし、何かツール使った方が良さそうだなあ。

続きを読む "java におけるメモリーリーク"

ソフト参照と弱参照

素敵な記事発見。メモ。

java にもメモリーリークの問題はあるわけで、そんなときに知った java.lang.refパッケージの存在。ずっとリフレクション関連だと思っていたけど、リファレンスだった。恥ずかしい。

ソフト参照はその性質から、通常のキャッシュ構造向き。弱参照は、生成コストが低いけれども大量のメモリを使用するデータ構造のキャッシュに向いている。弱参照は画像処理に使えそうだなあ、と思ったら、正規化マップがその典型例だそうで。やっぱり。

しかし、ソフト参照も弱参照も、実際の動作がいまいち見えてこないなあ。難しい。いろいろ試して肌で感じるしかないのかしらん。奥が深そうで、ワクワクしつつも逡巡する。

カスタムタグでEL式を使う

EL式 (Expression Language) がなかなか便利なので、カスタムタグでも使えると良いなあと思って試してみたら、できた。

結論から言うと、JSTL1.0 と JSTL1.1 では、EL式の挙動が異なる。そのため、それぞれの環境に合わせて、タグのクラスを用意する必要がある。これ、見事にハマりました。

<dt:format date="${row.date}" />

このようにEL式を指定した場合、JSTL1.0では${row.date}という文字列のままカスタムタグに渡されるのに対し、JSTL1.1では式言語を評価した結果がカスタムタグに渡される。だから、両者を書き換えるならば、アクセッサメソッド(setter)の型から変える必要さえあるということになる。0.1違うだけなのに、スゴイ変化だ。そのフットワークの軽さはうらやましいぞ。

以下、それぞれのサンプルソースですよ。

続きを読む "カスタムタグでEL式を使う"

ResourceBundle のメモリ管理

プロパティファイルが肥大化してきたので、ResourceBundle 使用時のメモリ効率が気になってきた。ムズムズと。

ResourceBundle クラスで読み込んだプロパティファイルのデータは、メモリ上に保持される。そのため、一度ファイルからデータを読んでしまえば、次回からのプロパティデータへのアクセスでは、IO に関するオーバーヘッドが無くなる。素敵だ。

しかし、ここで気になるのは、もしプロパティファイルに大量のデータがあった場合、メモリが食い潰されてしまうのではないかということ。

国際化対応に使われるくらいだから、ある程度のデータ量にも十分耐えうる仕組みを採用しているだろうと予想しつつも、そこで貴重なメモリ領域が、それなりに使われているのは確か。

で、ソースを追っていったら、読み込む bundle をソフト参照(SoftReference)で保持していた。つまり、メモリのことは JavaVM に任せておけば良いみたい。とは言え、bundle 単位で参照を持つので、あまり巨大なプロパティファイルを読み込むのは、結局メモリを圧迫してよろしくなさそう。ある程度は細分化して管理した方が、キャッシュ機能を有効に使えるかもしれない。

続きを読む "ResourceBundle のメモリ管理"

c:forEach varStatus のプロパティ一覧

JSTL の <c:forEach> は、strutsタグの <logic:iterate> に比べて格段に便利だ。最もその差を感じるのが、ループ内で扱えるステータス変数の扱いやすさ。

<c:forEach> のステータス変数が持つプロパティの一覧。

プロパティ機能初期値
varStatus.indexループインデックス0
varStatus.countカウント値1
varStatus.first最初の要素かどうかの真偽値
varStatus.last最後の要素かどうかの真偽値
varStatus.beginbegin属性値(開始値)
varStatus.endend属性値(終了値)
varStatus.stepstep属性値(増分)
varStatus.current現在値

first とか last とか、かゆいところに手が届いていて嬉しい。贅沢を言えるなら、perl の HTML::Template にあるような odd や even プロパティなんかあると、テーブルの縞模様とか二段組がカンタンに作れるのにね。

続きを読む "c:forEach varStatus のプロパティ一覧"

strutsタグとJSTLの対応表

今まで JSP で struts の bean タグや logic タグで記述していたところを、JSTLを使って書かなくちゃいけなくなった。めんどっちぃ。ということで、対応表。

struts taglibJSTL
bean:definec:set
bean:cookiec:set
bean:headerc:set
bean:parameterc:set
bean:messagefmt:message
bean:writec:out
bean:write format="yyyy/M/d"fmt:formatDate pattern="yyyy/M/d"
bean:includec:import
logic:emptyc:if test="${empty x}"
logic:notEmptyc:if test="${not empty x} != null"
logic:presentc:if test="${empty x}"
logic:notPresentc:if test="${not empty x} != null"
logic:equalc:if test="${x == 'abc'}"
logic:notEqualc:if test="${x != 'abc'}"
logic:greaterEqualc:if test="${x >= 0}"
logic:greaterThanc:if test="${x > 0}"
logic:lessEqualc:if test="${x <= 0}"
logic:lessThanc:if test="${x < 0}"
logic:iteratec:forEach

logic:match に対応するもんは無いのかな。どうせなら正規表現マッチとかできたら楽しいんだけどなあ。あとは、bean:size に対応するタグが無いのも痛い。JSTL1.1からある fn:length とか使うと良いっぽいけど、開発環境 JSTL1.0 だった気がする。でも、そのままでも、ちょっと工夫すれば取れるのか。

柔軟性ありそうな感じなんで、使っていくとハマるかな。

Hue Circle

huecircle.jpg

というわけで、Java で色相環を描いてみた。(1h)

ぐるり一周したところで、境界線が出てしまっているのが残念。色相角度の値を 1/360 ずつ加算して一周させたんだけど、float型の計算でどうしても誤差が出てしまう。計算部分の実装をうまく考えれば、もうちょっと精度を上げられそう。

今回、久しぶりに Applet を書いたんだけど、これまで気が付かなかった面白さを感じてしまった。ActionScript も良いけど、やっぱ Java ですよ、奥さん。そんなわけで、今さらハマりそうな予感。( processing でも良いんだけどね)

続きを読む "Hue Circle"

Color#RGBtoHSB

Java で色相環を描こうと思って、しこしこ RGB と HSV の変換クラスを作っていたら、何か Color クラスに RGBtoHSB なるメソッドがあるじゃないですか。こんな小さいとこで車輪の再発明してどうする。まあ、以前 Flash で同じことやろうとしたときの AS を、コピペしただけなんだけど。

float[] hsb = Color.RGBtoHSB(255, 0, 0, null);
hsb[0] += (float) 1/360;
Paint p = Color.getHSBColor(hsb[0], hsb[1], hsb[2]);

こんな感じでやればイケそう。

ちなみに、HSB は Hue(色相)、Saturation(彩度)、Brightness(明度) で構成されるカラーモデル。似た感じの HLS は Hue(色相)、Luminance(輝度)、Saturation(彩度) で成り立つ。明度と輝度の違いって、どのくらい認識されてるんだろう。