- PR -

staticメソッド内の内部(自動)変数

投稿者投稿内容
matu
ベテラン
会議室デビュー日: 2002/09/01
投稿数: 95
お住まい・勤務地: 東京
投稿日時: 2003-02-28 12:13
こんにちは。
非常に基本的な事で恐縮ですが、ご存知であればご教授下さい。

staticメソッド内部で宣言される自動変数(C言語的な表現ですが・・)
は共有でしょうか?(つまり排他制御が必要でしょうか?)

上記のケースのメモリの動きがどうもパッとしません。
・staticメソッドのプログラムコードは固定のメモリに割り振られる
・static内部の自動変数はスタック内部に取られる
この時AさんのCALLしたstaticメソッド、処理BさんのCALLしたstatic
メソッド、プログラムコードは共有だと思いますが、実行時の自動変数
は別管理になるのでしょうか?

よろしくお願いいたします。
DaikiRyuto
大ベテラン
会議室デビュー日: 2002/07/23
投稿数: 200
投稿日時: 2003-02-28 16:49
staticに限らず、メソッド内部で宣言された変数の領域用のスタックは別に取られると思ってよいんではないでしょうか。
matu
ベテラン
会議室デビュー日: 2002/09/01
投稿数: 95
お住まい・勤務地: 東京
投稿日時: 2003-02-28 17:16
 ありがとうございます。排他は必要ないという事ですね?

 今までスタック領域は別に取られるという思いでなんとなく
ServletやClassを作っていたので少し不安にかられてしまい
ました。
 例えば様々なサンプルはstaticでも内部変数レベルであれば
synchronizedなどは考えていないですし、Servletであれば
ほとんどのServletはSingleThreadModelを使っていません。
つまりクラス変数を意識しない限り排他を意識する必要は無い
ということですね?

 ちなみにスタックに取られた内部変数はどの様に管理される
のでしょうか?例えばAさんの使っている内部変数、Bさんの使っ
ている内部変数はどの様に別々に管理されているのでしょうか?
 もし良い参考ページなどご存知であればご教授下さい。

 よろしくお願い致します。
t-wata
大ベテラン
会議室デビュー日: 2002/07/12
投稿数: 209
お住まい・勤務地: 東京
投稿日時: 2003-02-28 18:12
> つまりクラス変数を意識しない限り排他を意識する必要は無い
> ということですね?

意味が良く分からないのですが、排他する必要があるのは、
インスタンス変数や、クラス変数を複数のスレッドから、
使う場合です。(final且つimmutableな変数は除く)

> 例えばAさんの使っている内部変数、Bさんの使っている内部変数
> はどの様に別々に管理されているのでしょうか?

Servletとかの話とごっちゃにしている?
内部変数は、スレッドごとに管理してます。それだけです。

matu
ベテラン
会議室デビュー日: 2002/09/01
投稿数: 95
お住まい・勤務地: 東京
投稿日時: 2003-02-28 18:46
>意味が良く分からないのですが、排他する必要があるのは、
>インスタンス変数や、クラス変数を複数のスレッドから、
>使う場合です。(final且つimmutableな変数は除く)

おかげさまで理解できた様です。immutableは初めて聞くので
調べてみます。単語から推測するとfinalと同様の意味合いで
しょうか?

>Servletとかの話とごっちゃにしている?
>内部変数は、スレッドごとに管理してます。それだけです。

説明不足で申し訳ございません。JVMもしくはOSのメモリ管理の
話しです。つまりGCなどのメモリ管理の部分はどの様なからくり
なのか?という部分まで疑問になってしまったので。。つい欲を
出して聞いてしまいました。
もし良い参考ページなどご存知でしたらご教授下さいm(__)m
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-03-04 11:08
unibon です。こんにちわ。

引用:

matuさんの書き込み (2003-02-28 18:46) より:

>内部変数は、スレッドごとに管理してます。それだけです。

説明不足で申し訳ございません。JVMもしくはOSのメモリ管理の
話しです。つまりGCなどのメモリ管理の部分はどの様なからくり
なのか?という部分まで疑問になってしまったので。。つい欲を
出して聞いてしまいました。


VM とか GC の細かいことは知らないのですが、
私の理解としては、Java の変数やインスタンスの排他制御に関して言えば、
「static かどうかは無関係です」
と言い切れると思います。
すなわち、static だからなにか特別なことがあるということはない、
ということを根底に置いて考えられると、話が簡単になって良いと考えます。


#以下、あとで追加しました。

ちなみに static 絡みの排他制御については過去記事の
件名:新人SEのためのJava講座についての質問
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=3038&forum=12
の前半部分あたりが近いと思います。
すでにご存知かもしれませんがご参考までに。

あと、ついでに補足としては、
とくに Java (に限ったわけではないですが)の特徴としては、
変数と、変数が指すインスタンス、は置き場(スタック/ヒープ)や管理方法が異なるので、
分けて考える必要があることに着目されるとよいかもしれません。

また、元記事のご質問についての直接の回答は、
私なりの多少ブロークンな回答になりますが、つぎのようになります。

>上記のケースのメモリの動きがどうもパッとしません。
>・staticメソッドのプログラムコードは固定のメモリに割り振られる

コードはどうなんでしょう。分かりません。
固定と言っても過言ではないような気もしますが。
普通は気にしなくて良いと思います。

>・static内部の自動変数はスタック内部に取られる

自動変数自身はスタックに確保されます。
ただし自動変数が指すインスタンスは、
スタックとは別のところに確保されます。
メソッド内で new したインスタンスだからと言って、
そのインスタンスがスタック内に確保されることはありません。
すなわち、スタックが管理するのは変数だけです。
変数が指すインスタンスはスタックでは管理されません。
(ただし new しないもの(int/long/double など)は、
変数がそれ自身の値を持ち、別にインスタンスを指さないので、
管理はスタック内に限定されます。)

>この時AさんのCALLしたstaticメソッド、処理BさんのCALLしたstatic
>メソッド、プログラムコードは共有だと思いますが、実行時の自動変数
>は別管理になるのでしょうか?

上述のようにコードは気にしなくてよいです。
自動変数は、A さんが使うスタックと B さんのスタックは同じはずはないので、
別管理です。
ちなみに、前回も書いたように static だからどうこうということは関係ありません。

#ついでのほうが長くなりました。


[ メッセージ編集済み 編集者: unibon 編集日時 2003-03-04 13:32 ]
tasuku
常連さん
会議室デビュー日: 2001/08/11
投稿数: 28
投稿日時: 2003-03-04 13:05
引用:

staticメソッド内部で宣言される自動変数(C言語的な表現ですが・・)
は共有でしょうか?(つまり排他制御が必要でしょうか?)



「staticメソッド内部で宣言される自動変数」はスレッド毎に
別の領域が確保されます。 が、プリミティブ型(って言って良いんだっけ...。)
と違って、Object変数は、所詮ポインターですから
こいつが指している実体へのメッセージはスレッドセーフとは限りません。

その辺は、大丈夫ですよね...。
matu
ベテラン
会議室デビュー日: 2002/09/01
投稿数: 95
お住まい・勤務地: 東京
投稿日時: 2003-03-04 13:20
引用:


こいつが指している実体へのメッセージはスレッドセーフとは限りません。

その辺は、大丈夫ですよね...。




 大丈夫ではないです…(汗)間違って認識していた様です。

 プリミティブ型以外はスレッドセーフにならないということですか?
 Object型の場合staticメソッド内で新規生成されたインスタンスは
・インスタンスの領域がメモリに確保される(JVMが管理)←ココ
・スタックにObjectの参照が格納される(これはスレッドセーフ)

 上記「JVMが管理」というところが危険という事ですか?つまりstatic
内部のObject型変数なのでJVMは共通のメモリ領域の参照を返す可能性が
あるということでしょうか?

 でも少し疑問が残るのですが、例えばServletのメソッドを作る場合など
は特別なケースを除いて「SingleThreadModel」をimplementsしませんよ
ね?また、良く見かける(文字列操作のクラスなどの)サンプルなども
staticメソッドで提供されますが、内部のObject変数(StringBuffer等)
へのスレッドセーフは特に意識していない様に思えるのですが。


[ メッセージ編集済み 編集者: matu 編集日時 2003-03-04 13:34 ]

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