虎塚スマートフォン用の表示で見る虎塚この広告は、90日以上更新していないブログに表示しています。納涼会-」へ行ってきました。当日は、ほろ酔いで帰ってきて、スタックマシンを書いて遊んだら満足して寝てしまったので、改めてセッションのメモと感想を書いておきます。パソコンを忘れて行ったこともあり、メモをあまり取っておらず、記憶に頼って書きました。間違いがありましたら、ぜひ教えてください。http://www.slideshare.net/skrb/java-vm-as-stackmahineスタックマシンとしてのJVMがバイトコードをどうやって実行するか、というテーマでした。いつも通り、音楽と写真が素敵なプレゼンテーションでした。1.4のコードネームは、Merlinでしたね。LinkedList口頭でいくつか補足されたことがありました。1つ目は、LinkedListでキューを実装したときは、キューらしくない振る舞いを避けよう、という話です。キュー、双方向キュー、スタックなどは、表に挙げたクラスのほかに、LinkedListでも実装できます。LinkedListを使うと、リストの途中の値を出し入れできてしまいます。いったことはやめておいた方がよいでしょうとのことでした。2つ目は、スタックを実装するときにjava.util.Stackを使わないでね、という話です。常識だからか、理由の説明は省略されましたが、調べた上で、身内のJavaに詳しい人に教えてもらいました。Vector、Stack、HashTableを現在使わない理由は、主に2つだそうです。Frameworkが導入される前から存在する)Vector、Stack、HashTableは、メソッド単位での同期を行うが、同期が必要ならば、インスタンスを同期するなりAtmicReferenceを使うなりするのが現実的なので、使う意味がない使ってはいけないというよりも、使う理由がないって感じなんですね。(合っているでしょうか?)ちなみに、StackOverFlowでは、次の解答が支持を集めていました。さくらばさんからコメントで補足を頂きました。Vectorはすべてのメソッドが同期化しているため同期化が必要ない場合はパフォーマンスが悪い。absentのようなトランザクションに対しては意味をなさない。全部synchronizedしてしまっているので、複数スレッドが同時にアクセスするような場合はボトルネックになってしまう。通常はreadは複数スレッドでもOK、writeは1つのスレッドというようにしないとパフォーマンスが伸びません。これに対して、同期が必要な場合はjava.util.concurrentパッケージで定義されているコレクションクラスを使います。ListであればCopyOnWriteArrayListなど、MapはConcurrentHashMapなどを使用します。四則演算を例に、スタックマシンの動作が解説されました。スタックマシンのハードウェアは、今ではもうほとんどないそうです。仮想マシンの実装にはまだまだあり、そのひとつがJVMです。JVMには、2種類のスタックがあります。StackJVMで使われるスタックの動きは、こうなります。スレッドの中には、プログラムカウンタとJavaスタックがあり、メソッド呼出しごとにJavaスタックにFrameが入っていきます。Stackと、ローカル変数が格納されるスタック配列があります。メソッドの戻り値がスタックに積まれます。......と、このあたりは、やっぱり是非さくらばさんの発表資料でご覧ください。写真のおかげで、とても分かりやすかったです。javapのお話が少しあって、これも勉強になりました。繰り返し実行されるメソッド呼出しがあり、呼び出されるメソッドの処理内容が簡単な場合、実行時に呼出し先のコードを呼び出し元に展開します。インライン化が発生する条件は、おそらく、バイトコードに変換したときに、よりサイズが小さくなると計算された場合、だそうです。7〜)生成したオブジェクトがFrameから逃げださないのであれば、OperandStackに置きます。「Frameから逃げ出さない」という言葉の意味がピンとこなかったのですが、「そのオブジェクトが別のFrameから参照されることがない」という意味でしょうか。8〜?)末尾再帰のコードをループとして実行します。末尾再帰によるメソッド呼出しのたびに新しいFrameが作られて、ついにはStackOverFlowが発生するような事態が、これで回避される可能性があります。このくだりで、うまく言葉にできなくて、質問できなかった疑問があります。さくらばさんは、次のようにおっしゃったと思います。末尾再帰の最適化をJVMが実装することで、これまで末尾再帰を独自に最適化していた(Java以外の)言語も、インライン化などのJVMの最適化の恩恵を受けられるようになります。(ちょっと違うかもしれませんが...)これは、JVM上で動く言語が、自前で末尾再帰を最適化していた場合は、JVM上での最適化の恩恵を受けられない、というように聞こえました。してそうなるのでしょう?末尾再帰の最適化が行う処理は、再帰をループに変更して、メソッド呼び出しのFrameの積み上げを減らす作業です。これは、メソッドのインライン化がもたらす結果と似ています。コンパイラが末尾再帰を最適化すると「JVMのインライン化が効かない」のではなく、「JVMがインライン化を行う余地が減る」という感じでしょうか。......身内からはそういったコメントをもらいましたが、サテハテ。ここは、よく分かりませんでした。さくらばさんからコメントで補足を頂きました。このように実行時にJavaであれば必要がない処理を必要とする場合あるため、Javaと同じような最適化ができない場合があるということです。http://d.hatena.ne.jp/torazuka/20120903/jjug#c1346765294(このように、の詳細は、コメント欄を参照ください)...動的な動作をさせるための実行時の処理の結果、最適化しにくいコードが生成されることもある、ということなのですね。invokedynamicについては、発表でも触れられていましたが、今回のまとめでは(自分の理解が浅いので!)省いてしまいました。