- PR -

コンスタント値専用クラスについて

投稿者投稿内容
matu
ベテラン
会議室デビュー日: 2002/09/01
投稿数: 95
お住まい・勤務地: 東京
投稿日時: 2003-03-01 12:54
 2件連続の投稿で恐縮です。

 システム全体で使用するコンスタント値についてですが、
皆様はどの様にされているのでしょうか?何が最適かご意見
をお聞かせ頂けたらと思います。

 私は現在
・コンスタント値専用クラスを作っている
・ResourceBundleでテキストプロパティーを使う
 の2つなのですがResourceBundleはほとんど使わずに1番目
のコンスタント値専用クラスを使っています。

 そこで2つほど疑問なのですが
1、他にもっと良い方法があるのでしょうか?
2、public final staticで全て宣言しているのですが、この
  値は実行時にclass丸ごとメモリロードでしょうか?又は
  コンパイラがコンパイル時に部分的にコンスタント値として
  展開してくれる方法?の様なものは無いでしょうか?

 なぜこの様な質問をするかと言いますと、最近そのクラスが
大きくなりすぎて、メモリの動きが心配になってきたからです。

 なにか良い方法をご存知であればご教授ください。
うのきち
ベテラン
会議室デビュー日: 2003/02/17
投稿数: 55
投稿日時: 2003-03-01 23:38
私は、基本的には、タイプセーフenumを使っています。

定数クラスが、メモリ消費に与える影響なんて、たかがしれていると思いますよ。気になるようなら、プロファイラ使って、測定してみるといいと思います。
katsum
大ベテラン
会議室デビュー日: 2002/02/27
投稿数: 119
お住まい・勤務地: 東京都
投稿日時: 2003-03-02 00:41
>タイプセーフenum
え!?Java に enum があったんですか!
元々 C 使いなもので、Java でも enum 使いたかったんですが、
言語仕様もひととおり読んだのですが見当たらなくて、
うのきちさんと同じく public final static してました。
できたら具体的なコードで少し教えていただけないでしょうか。
katsum
大ベテラン
会議室デビュー日: 2002/02/27
投稿数: 119
お住まい・勤務地: 東京都
投稿日時: 2003-03-02 00:43
>うのきちさんと同じく public final static してました。
あらら、matu さんの間違いでした。すみません。
kage
会議室デビュー日: 2003/03/02
投稿数: 1
投稿日時: 2003-03-02 02:21
やはり私もjavaでenumは初めて聞いてます。C++ではありませんか?

public final static何ですが、一回そのクラスが呼ばれたらすべてのコンスタント値が
メモリにロードされます。ですがガベージコレクション処理が行ったらメモリから開放されます。
Out of Memoryを防ぐためにはスレッドで周期的にメモリを監視し、もしある程度メモリが少なくなったらSystem.gc()を・・

以下のソースでテストして見ました。
簡単なソースなのでコンパイルして試してください。

------------Test.java----------------
import java.lang.*;

public class Test {
public static void main(String[] args){

Runtime rt_;
rt_ = Runtime.getRuntime();

long total = rt_.totalMemory() / 1024;
long free = rt_.freeMemory() / 1024;
System.out.println( "final static unroaded ==> !!!!!!!!!! total = " + total + "kb free = " + free + "kb !!!!!!!!!!" );

//TestFinal class load
int test_int = TestFinal.intdata1[1000];

total = rt_.totalMemory() / 1024;
free = rt_.freeMemory() / 1024;
System.out.println( "final static roaded ==> !!!!!!!!!! total = " + total + "kb free = " + free + "kb !!!!!!!!!!" );

System.gc();

total = rt_.totalMemory() / 1024;
free = rt_.freeMemory() / 1024;
System.out.println( "gabage collection execited ==> !!!!!!!!!! total = " + total + "kb free = " + free + "kb !!!!!!!!!!" );

}
}

------------TestFinal.java----------------
import java.lang.*;

public class TestFinal{
public final static int[] intdata1 = new int[10000];
public final static int[] intdata2 = new int[10000];
public final static int[] intdata3 = new int[10000];
public final static int[] intdata4 = new int[10000];
public final static int[] intdata5 = new int[10000];
}

asip
ベテラン
会議室デビュー日: 2001/12/27
投稿数: 77
投稿日時: 2003-03-02 07:25
>うのきちさん
>私は、基本的には、タイプセーフenumを使っています。
Javaにenum型は存在しません。C#にはあるようですが...。
JavaとC#はよく似ていますが、異なる部分が多々あります。

>最近そのクラスが大きくなりすぎて、メモリの動きが心配になってきたからです。
constantパッケージでも作成してクラスを分割されてはいかがでしょうか?
参照されないクラスはGCの対象となるので1つの大きなクラスよりはいいように
思います。一つの大きなクラスでは常にどこかで参照されていて全体がロード
されている状態になるので...。
matu
ベテラン
会議室デビュー日: 2002/09/01
投稿数: 95
お住まい・勤務地: 東京
投稿日時: 2003-03-02 10:14
 書いていたらいつのまにかセッションが切れていました。。
もう一度書きなおしです。

 enumは確かにC#の機能の様ですね?Cでの開発体制の時には
サブシステム単位にシステムリーダが構造体定義でコンスタント
管理していました。だいぶ昔の話なのでうるおぼえですが、C#の
enumも同様にコンスタント管理に活躍しそうですね?違うかな?

 ちょっとC#で思い出したのですが、皆さん携帯のBREWってご
存知ですか?ネイティブコードを生成する為の開発platformは
c、c++の様です。c#やjavaはout of the questionになるので
しょうか?今携帯のアプリに何を使うかという話題はとてもhot
な話題なので気になって眠れません。。というのは冗談ですが。
 すみません、全然違う話題で。。

 本題ですが、kageさんに教えていただいた方法で確認体制を
作ってみたいと思います。最近EJBなのでメモリが気になってい
たので。またコンスタントパッケージは良い方法ですね。確かに
GCがこまめにcleanできるので効果的です。

 ありがとうございました。
DaikiRyuto
大ベテラン
会議室デビュー日: 2002/07/23
投稿数: 200
投稿日時: 2003-03-02 12:35
引用:

matuさんの書き込み (2003-03-01 12:54) より:

 私は現在
・コンスタント値専用クラスを作っている
・ResourceBundleでテキストプロパティーを使う
 の2つなのですがResourceBundleはほとんど使わずに1番目
のコンスタント値専用クラスを使っています。

 そこで2つほど疑問なのですが
1、他にもっと良い方法があるのでしょうか?
2、public final staticで全て宣言しているのですが、この
  値は実行時にclass丸ごとメモリロードでしょうか?又は
  コンパイラがコンパイル時に部分的にコンスタント値として
  展開してくれる方法?の様なものは無いでしょうか?



1についてですが、テキストプロパティにはPropertiesとResourceBundleの違いがあると思います。
あと、私は使用したことがありませんがXMLという選択肢もあるのでは、と思ってます。.NETのプログラムなどとデータを共用できるのではないか、と期待しています。

2ですが、public static finalな定数はコンパイル時に埋め込まれます。
したがって値を変更した場合は、関連するすべてのクラスの再コンパイルが必要になります。
http://www.gimlay.org/~javafaq/S012.html#S012-05
リフレクションの機能などを使用していなければ定数クラスはロードされないのではないかと思いますが、確信はありません。

kageさんの示されているような、配列をpublic static finalにするパターンは初めてみましたが、これについてはわかりません。おそらく参照先変更不可な配列参照変数になるんでしょう。ガベージコレクションが実行されたあとも変数の参照先は同じ場所でしょう。生成される配列自体は変更不可にはならない……と思います(^_^;(自信無し)

スキルアップ/キャリアアップ(JOB@IT)