谷本 心 in せろ部屋 このページをアンテナに追加 RSSフィード

2015-12-24

[][]JMXで情報を取得する時のベンチマーク

JMHを使って、JMX経由でMBeanの情報を取る際のパフォーマンスを測定してみた。

ベンチマークソースコードはこちら。

https://github.com/cero-t/Benchmarks/blob/master/src/main/java/ninja/cero/benchmark/JmxBenchmark.java


ベンチマーク環境はMacBook Pro Late 2013 (Core i5 2.4GHz) で、

他のアプリなども立ち上げっぱなしの環境なのでノイズは多めでだけど、

傾向を見たいだけなのであまり気にせず。


VirtualMachine.attachのパフォーマンス

VMオンデマンドアタッチする際のパフォーマンス。


No1 : VirtualMachine.attacheしてからシステムプロパティを取ってdetachする

No2 : キャッシュしていたVirtualMachineを使ってシステムプロパティを取得する

@Benchmark
public void no1_vmAttach() throws Exception {
    VirtualMachine vm = VirtualMachine.attach(PID);
    vm.getSystemProperties();
    vm.detach();
}

@Benchmark
public void no2_vmCachedGetProperties() throws Exception {
    vm.getSystemProperties();
}

結果

BenchmarkModeCntScoreErrorUnits
JmxBenchmark.no1_vmAttachthrpt10653.834± 108.790ops/s
JmxBenchmark.no2_vmCachedGetPropertiesthrpt102330.529± 270.268ops/s

アタッチありは1.5msec程度、キャッシュした場合は0.4msec程度。

ということで、アタッチに掛かる時間は1msec程度と推定。割とでかい。


JMXConnectorFactory.connectのパフォーマンス

続いて、VMに対するJMX接続を行う際のパフォーマンス。


No3 : JMXConnectorの取得処理と、クローズ処理をする

No4 : キャッシュしていたJMXConnectorを使って、MBeanServerConnectionの取得とMbean情報を取得する

public JMXConnector no3_vmCachedGetConnector() throws Exception {
    String connectorAddress = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress");

    if (connectorAddress == null) {
        String agent = vm.getSystemProperties().getProperty("java.home") + File.separator + "lib" + File.separator + "management-agent.jar";
        vm.loadAgent(agent);
        connectorAddress = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress");
    }

    JMXServiceURL serviceURL = new JMXServiceURL(connectorAddress);
    JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceURL);
    jmxConnector.close();
}

@Benchmark
public void no4_connectorCachedGetMBeanCount() throws Exception {
    MBeanServerConnection connection = connector.getMBeanServerConnection();
    connection.getMBeanCount();
}

結果

BenchmarkModeCntScoreErrorUnits
JmxBenchmark.no3_vmCachedGetConnectorthrpt10612.652± 95.547ops/s
JmxBenchmark.no4_connectorCachedGetMBeanCountthrpt109047.803± 1480.741ops/s

JMXの接続と切断は1.6msec程度。おおまかVMに対するアタッチと同じぐらい。

接続したあとの、MBeanServerへの接続とMBean情報取得は0.1msecぐらいで、これは無視できる小さい。


ThreadMXBeanからThreadCountを取るパフォーマンス

今回の主目的はこれ。

ThreadMXBeanを使って情報を取るのと、

MBeanServerConnection.getAttributeで名前を指定して情報を取るのと、どっちが早いか。


No5 : MBeanServerConnection.getAttributeの名前指定でThreadCountを取得する

No6 : ThreadMXBeanを取得してから、getThreadCountで取得する

No7 : キャッシュしていたThreadMXBeanから、getThreadCountで取得する

@Benchmark
public void no5_connectorCachedThreadCount() throws Exception {
    MBeanServerConnection connection = connector.getMBeanServerConnection();
    Object count = connection.getAttribute(new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME), "ThreadCount");
    sum += (Integer) count;
} 

@Benchmark
public void no6_connectorCachedGetThreadCount() throws Exception {
    MBeanServerConnection connection = connector.getMBeanServerConnection();
    ThreadMXBean threadBean = ManagementFactory.newPlatformMXBeanProxy(
            connection, ManagementFactory.THREAD_MXBEAN_NAME, ThreadMXBean.class);
    sum += threadBean.getThreadCount();
}

@Benchmark
public void no7_beanCachedGetThreadCount() throws Exception {
    sum += threadMXBean.getThreadCount();
}

結果

BenchmarkModeCntScoreErrorUnits
JmxBenchmark.no5_connectorCachedThreadCountthrpt108199.887± 1269.164ops/s
JmxBenchmark.no6_connectorCachedGetThreadCountthrpt102662.147± 585.627ops/s
JmxBenchmark.no7_beanCachedGetThreadCountthrpt108148.967± 1705.518ops/s

ThreadMXBeanを毎回取る(No6)は明らかにパフォーマンスが悪いけど、

ThreadMXBeanをキャッシュしている限りは、ThreadMXBeanから情報を取るのと、

MBeanServerConnection.getAttributeで取ることに性能差はなし。


まとめ

1. VirtualMachineへのattach/detachは時間が掛かるので、キャッシュすべき

2. JMX接続の確立/切断は時間が掛かるので、キャッシュすべき

3. MBeanServerへの接続は時間が掛からないので、無理にキャッシュしなくてよい(close処理もないのでリソース管理もしてない?)

4. MBeanServerConnection.getAttributeでもThreadMXBeanを使っても性能差はないので、ThreadMXBeanを無理にキャッシュしなくてよい


ベンチマークソースコード

https://github.com/cero-t/Benchmarks/blob/master/src/main/java/ninja/cero/benchmark/JmxBenchmark.java


現場からは以上です。

2015-10-19

[]DynamoDBでTomcatセッション共有をするとハマるかも

AWSを仕事で使い始めて1年半、

ようやく頭がクラウド脳に切り替わってきた @ です。

好きなAWSサービスはKinesisです。まだ使ってませんけどね!


さて、今日のテーマは「AWSTomcatセッション共有」です。

EC2上で動くTomcatセッションオブジェクトを、DynamoDBを使って共有するというものです。


話題としてはそれなりに枯れていると思うのですが、

案件で使おうと思ったら問題が出そうになって困ってる、という話です。


発生する問題は?

どういう問題が起きるか、先に書いておきます。


発生する問題は、

複数のTomcatをELBで分散させている時に、

スケールインやスケールアウトが短時間に連続して発生すると、

セッションが巻き戻る(先祖返りする)可能性がある、というものです。


セッションが消えるならまだしも、

先祖返りするというのは、実案件において許されない感じです。


あっ、

そもそも「セッションなんか使うから問題が起きるんだ」というツッコミはナシでお願いします。

それは分かったうえで、やむを得ずセッションを使うならどうしようか、という検討なのです。


Tomcat + DynamoDBの組み合わせ方

Tomcatセッション共有になぜDynamoDBを使うのか、どういう設定をするのか、

というのは、この辺りのエントリーで学びました。


Amazon DynamoDBによるTomcatセッション永続化とフェイルオーバー - Developers.IO

Tomcat 7.x時代の記事ですが、考え方や注意点がとても分かりやすく紹介されています。


AWSでセッションをクラスタリングする方法について考えてみた結果、DynamoDBがよさそうなので試してみた。 - Qiita

Tomcat8 / Spring Boot / DynamoDBの連携がかなり詳しく紹介されています。


これらのサイトでも紹介されている内容を踏まえると、

以下のような流れになりそうです。

1. ELBの設定でスティッキーにして、同一セッションIDは同じTomcatに振り分ける

2. TomcatからDynamoDBに非同期で書き込む。遅延時間は調整可能(最低1秒?)

3. Tomcatセッションを持っていない場合に限り、DynamoDBを参照する。

 (スケールイン / スケールアウトなどが起きた時に、セッションを引き継ぐことができる)


この流れは、いわゆる「リードスルー方式」と「ライトビハインド方式」を組み合わせたものだと言えます。

一見、この流れで問題がなさそうなのですが、

よくよく考えるとセッションの巻き戻しが起きることが分かりました。


どういう時に問題が起きる?

問題の再現状況は以下の通りです。

  • ELB
  • Tomcat 2台(仮にTomcat1、Tomcat2と呼ぶ)
  • DynamoDB

この構成で「フェイルオーバー → 復帰 → フェイルオーバー」を、

セッションタイムアウトよりも短い時間内で繰り返すと、問題が発生します。


時系列で順を追って説明しますね。


(1) Tomcat1 + DynamoDBにセッション保持(Tomcat1 → DynamoDB)

ユーザがアクセスした際に、ELBによってTomcat1に振り分けられたとします。

以後、このユーザは必ずTomcat1に振り分けられるため

ユーザがセッションに書き込んだ内容は、Tomcat1からDynamoDBに永続化され

Tomcat1のメモリとDynamoDBの両方で保持されることになります。


(2) フェイルオーバー(DynamoDB → Tomcat2)

ここでELBからTomcat1への振り分けを遮断すると、

ユーザのアクセスは、ELBによってTomcat2に振り分けられます。

ここでセッション情報はDynamoDBからTomcat2にロードされるため

これまで蓄積してきたセッション情報が消失することも、巻き戻ることもありません。


(3) Tomcat2 + DynamoDBにセッション保持(Tomcat2 → DynamoDB)

ユーザのアクセスはTomcat2に振り分けられていますので

ユーザがセッションに書き込んだ内容は、

Tomcat2のメモリとDynamoDBの両方で保持されます。


(4) Tomcat1の復帰(DynamoDB → Tomcat1)

次に、ELBからTomcat1への振り分けを再開すると

ユーザのアクセスは、Tomcat1に振り分けられます。

(Tomcat2に固定されず、Tomcat1に戻るんですよね)


Tomcat1を一度再起動するなどして、メモリにあったセッション情報を空にしておけば

最新のセッション情報がDynamoDBからTomcat1にロードされるため

やはりセッションの巻き戻しはありません。


(5) Tomcat1 + DynamoDBにセッション保持(Tomcat1 → DynamoDB)

この状況でユーザがセッションに書き込んだ内容は、

Tomcat1のメモリとDynamoDBの両方で保持されます。

ここまでは問題ありません。


(6) 改めてフェイルオーバー(Tomcat2のみ)

ここで再度ELBからTomcat1への振り分けを遮断すると、

ユーザのアクセスは、ELBによってTomcat2に振り分けられます。


この時、Tomcat2のメモリ内には (3) の時に書き込んだセッション情報が存在するため

わざわざDynamoDBを読みに行かず、Tomcat2が保持しているセッション情報を利用します。

そのため (5) で更新した内容から (3) の内容まで、巻き戻しが発生してしまいます。


つまり、0〜1秒ぐらいのタイミング問題(避けられない事故)ならまだしも、

数分ぐらいのオペレーションでも、セッションの巻き戻りが起きることになります。


じゃぁどうするの?

ここまで見てきた通り、書き込みが非同期である以上、

巻き戻りの問題が発生することは避けられません。


もちろん運用上、このような操作(短時間でのフェイルオーバー)を行なわないようにするのは一つの解ですが、

たとえば「リリース失敗時の切り戻し」なんてことを考えると、発生する可能性はゼロではありません。

そのため「買い物カゴ」のような、巻き戻りが業務に影響してしまうものは、この方式では扱えません。


では、設定を修正して何とかできないか考えてみます。

そもそも「非同期書き込み」と言えば、リードスルー / ライトビハインド方式以外にも

 1. ライトスルー方式(DynamoDBの更新時に、全Tomcatも同時に更新する)

 2. Tomcatのメモリを一切使わない(セッションの読み書き時には必ずDynamoDBを利用する)

の2つが考えられます。


ただ、TomcatのPersistenceManagerを利用する限りは、

どう設定しても1にも2にもならないことが分かりました。


そもそもPersistenceManagerはセッション共有の仕組みではなく、

JavaVMのヒープを過剰に占有しないために永続化するものです。

それをセッション共有のために代用しているだけであり、

本気でセッション共有を考えられたものではありませんでした。


・・・という事で、今回は、セッションを利用することを諦めました (^^;

最初に「セッション使うなっていうツッコミはナシ」とか言っておきながら、すみません (^^;;


まず「買い物カゴ」のような、決して巻き戻ってはいけない重要な情報は

セッションで扱うことを諦め、直接DBに永続化することにしました。


一方で「ログイン情報」や「行動をトレースするための情報」など、

最悪、多少巻き戻っても業務に影響しないような情報のみ、セッションに残すようにしました。


ちゃんちゃん♪


他の選択肢 - Spring Session

そんなわけで、DynamoDB、というか、

PersistenceManagerを利用したセッション共有は、お手軽にできるものの、

問題がありそうだという結論に至りました。


それでもセッション共有は諦めきれず、

他の選択肢として Spring Session を確認してみました。

Spring Sessionは、Redisなどをバックエンドとして利用できるセッション共有の仕組みです。


軽くソースを読んでみたところ

 1. session#setAttributeすると「差分データ」として内部で保持される

 2. ServletFilterで、処理の終了後に「差分データ」をまとめてRedisに反映させる

 3. session#getAttributeしたオブジェクトに対して操作しても、差分は反映されないので注意

ということが分かりました。

この仕組みなら、フェイルオーバー時の挙動もあまり問題にならなさそうです。


ただ、2の通り、セッションには即時反映せず、リクエスト終了時に反映するため、

たとえば同一セッションで複数リクエストを処理する際には、

(たとえば同一セッションから同時にアクセスカウンターをインクリメントしようとしても)

上手くいかないことがありそうです。


即時反映をサポートをして欲しいというチケットが挙がっているので、

将来的には即時反映がサポートされるかも知れません。

https://github.com/spring-projects/spring-session/issues/250


また3の制約により、既存のアプリケーションにSpring Sessionを適用する場合には

多少ソースを改修しなければいけないこともあるでしょう。


そんな理由で、今回は採用を見送りました。

今後の案件でSessionを使わざるを得ない場合に、改めて検証してみたいと思います。


まとめ

1. TomcatのPersistenceManager + DynamoDBなどによるセッション共有は、

 書き込み遅延や、フェイルオーバー時の巻き戻りを受け入れざるを得ない。


2. Spring Session + Redisによるセッション共有は、

 同一セッションでの複数リクエストへの考慮をすること、

 セッション更新時に、きちんとsession#setAttributeすることをルール化すれば、

 それなりにきちんと使えそう。


3. そもそも、絶対に巻き戻っちゃいけないトランザクショナルなデータは

 セッションなんてあいまいなものに持たせず、RDB管理しようぜ。


まぁ結局、セッション使うなという所に戻ってくるのは、何ともですね。

2013-10-02

[]俺様とJavaOne 2013(後編)

いよいよJavaOne最終日です。

最終日はCommunity Keynoteと、いくつかのセッションを行なうだけで

夕方ぐらいには閉幕してしまいます。


Day 5 : 子供のプログラミング、どうしていますか?

Community Keynote

最終日、最初のセッションはコミュニティキーノート、

かつては、Gosling's Toy Showなどが行なわれていたイベントですね。

このキーノートで日本の皆さんにお伝えしたい事は、ただ一つ。


#てらだよしお が、Tシャツを投げていました!


あぁ、写真とか撮ってないです、すみません。

たぶん誰か撮ってます、そっちに期待してください。


私の席からは見えませんでしたが、James GoslingもTシャツを投げていたそうなので

この瞬間、てらだよしおはJames Goslingに匹敵するエンジニアだった、ということですね!


それはさておき、

このコミュニティキーノートで一番印象に残ったのは、教育の話です。

10〜14歳の子供を対象にしたDevoxx 4 kidsというイベントの様子が紹介され、

子供が「やった、動いた!」などと言いながら、プログラミングを楽しんでいました。


また、会場にはArun Guptaの10歳の息子、Aditya Guptaが登場して、

Minecraftというゲームをハックした時の考え方などを紹介しました。

「これはEclipseという開発環境で」「左側のソースファイルの一覧があって」などと

10歳の子供が説明するだけで会場は大盛り上がりなのですが、

恐らく、彼自身はなぜ会場が盛り上がっているのか分からなかったに違いありませんw


10歳の子供が、数千人(?)の大人を相手に、

大して緊張する様子もなく、声を震わすこともなく、説明しきった様子は圧巻でした。

会場のスタンディングオベーションも、決して過大評価ではなかったと思います。

本当に素晴らしかったです。


Devoxx 4 kidsの動画や、Aditya Guptaの発表を見るにつけ、

同世代の子供を持つ親としては、そろそろ子供に楽しいプログラミングを

教えてもいいかな、という気持ちになってきましたね。


私自身、プログラミングを始めたのは、この年代だったと記憶しています。

一つの素養として身につけるには、決して早くない時期でしょう。


今度、科学未来館に行って、プログラミングできるおもちゃを買ってくるかな。


[CON4695] Java Memory Hogs

OracleのNathan Reynoldsによるセッション

Keynoteが終われば帰る人も多い中、部屋は満席で立ち見が出るほどでした。

やっぱりメモリ系やGC系セッションは人気があります。


本当はこの前にいくつかのセッションを入れていたのですが、

Community Keynoteの後にJames Goslingとの記念写真撮影に並んでいるうちに

予約していたセッションが満席になってしまったり、

ランチで少し遠目に出ているうちに逃してしまったりなどして、

最終日のセッションはこれ一本になりました。てへぺろ。


さて、

このセッションのテーマはJOverflowを使ったヒープメモリの診断です。

というかJOverflowって、ただのヒープダンプを解析できるだけではなくて、

無駄なヒープの使い方を指摘する機能まであるんですね。いいですねこれ。


このセッションでは、実際のJavaEEアプリケーションのヒープダンプを取り、

それをJOverflowで診断して検出した問題について、改善方法や結果が示されました。


たとえば英数字しか入らないStringをcharではなくbyteで保持したら

7%ぐらいメモリ効率が上がったとか

同じ文字列のStringがたくさん重複していたからString.intern()で改善したとか

空の配列やCollectionがたくさんあったからLazy初期化するようにしたとか

そういう話です。


このセッションを通して感じたことは

「JOverflowは、ヒープダンプのFindBugs」だということですね。


たとえば空のCollectionがたくさんあるとか、

同じ文字列のStringの重複がたくさんあることなどは、

理論上は「減らせば良い」わけですが、Lazy初期化やinternを使った処理を書くとなると

パフォーマンスへの影響や、可読性の低下(処理の複雑化)は多少なりあるため

なかなか全ての場所で、理論通りにコーディングするわけにもいかないと思います。


その点、JOverflowを使い、実際に動かしたアプリケーションのヒープダンプを解析することで

「本当に問題になるところ」が分かるため、実際的に改善すべきポイントを掴めるわけです。

このアプローチ、まさにENdoSnipeと同じですね!(←これが言いたかったの?)


大事なことなのでもう一度言いますが、

「JOverflowは、ヒープダンプのFindBugs」です。

ぜひ試してみましょう。


JavaOne 2013最後のセッションでしたが、かなり面白い内容でした。


JavaOneを終えて、最後に。

そんなわけで、これでJavaOne 2013は終わりです。


今年のJavaOneで一番印象的だったことは、

もちろん私自身が初めてスピーカーを務めたことですが、それを除けば、

子供へのプログラミング教育の話でした。


同世代の子を持つ私としては、

Devoxx 4 kidや、10歳のAditya GuptaによるCommunity Keynote発表などは

非常に印象的でワクワクすると同時に、負けていられないという気持ちになりました。


一方で、Javaも転換期に来たのかな、という印象もありました。


少し話はそれますが、

先日、「教育」に関する有名ブロガーのつぶやきが話題になりました。

人が教育の話をしはじめるのは、自分の成長に限界が見えた時、

要するに「自分の成長よりも、後進の成長のほうが価値がある」と考えるようになった時だ、

というアレです。


この話も踏まえると、このJavaOneで「子供の教育」の話がなされるというのは

多くのJavaの開発者たちが、あるいは、Javaそのものが転換期に来た、

悪く言えば「焼きが回った」ところにさしかかったのかな、という印象になったわけです。

いや、たぶんに感覚的な話なんですけどね。


また、今回は新しい情報がほとんどないJavaOneでしたが、

個人的に(弊社的に)言えば、Flight RecorderやMission Controlの

裏側の仕組みや、今後目指すところを聞いたことで、

ENdoSnipeの開発も改めて頑張ろうという気になりました。


ENdoSnipeを、Duke's Choice Awardをとれるぐらいの秀逸なプロダクトにしたいなと、

そんな大きな野望を持ちながら帰国の途につきました。


よし、頑張ろう!

2013-09-30

[]俺様とJavaOne 2013(中編)

JavaOne 3日目、自分のセッション当日は

やっぱり直前まで資料準備&練習でバタバタしていました。

この性格、死ぬまで治らない予感!


Day 3 : 解析ツールのセッションは人気

3日目、僕のセッションは夜7時半からなので、

朝イチにあった面白そうなセッションに参加していました。


[CON5092] Diagnosing Your Application on the JVM

元BEAのStaffan Larsenのセッション

朝イチにも関わらず、満席になる人気セッションでした。


内容は、診断・解析ツールについて、デモを交えて次々と紹介するセッション

主に7u40から使えるようになった(7u4から使えてたものもあるけど)

「jcmd」(旧jrcmd)を中心に紹介されていました。


ちょっと列挙しますと・・・

jps : Javaプロセスの一覧を列挙する

jcmd : 引数なしならjpsと同じ

jcmd <pid> VM.uptime : Javaプロセスの起動後の経過時間

jcmd <pid> Thread.print : スレッドダンプ。jstackと同じ。

jcmd <pid> GC.heap_dump : ヒープダンプ。jmapと同じ。

jcmd -gcnew <pid> 1s : 毎秒のGC領域のサイズを見る

jcmd <pid> PerfCounter.print : JVM内部で保持している様々なカウンタを取得

などなど。


自分的に衝撃だった事と言えば、jcmdコマンドの引数で pid に 0 を指定すると

全てのJavaプロセスの情報をまとめて取れる、というところ。

実際に使う機会があるかどうかは分かりませんが、良い事を知った感がありますね(笑


またセッション後半は、このような解析ツールをリモートから実行するために、

jstatdやJMX Remoteを利用するという話や、その裏側の仕組みが説明されました。


正直、他の作業をしながら聞いていたので、かなり聞き逃してしまったのですが

リモートから診断・解析をする時に、何ができるか・できないかを判断するための

背景となる知識が得られる良い内容でした。まさにJavaOneらしい内容だったと言えます。


特に解析する機会が多いとか、開発ツールを作る立場であるとか、

そういう人は、このセッションの資料をきちんと読むべきだと思いますね、

っていうか、私も、きちんと読み直します!


ところで、セッションの後に

こんな風にスピーカーのStaffanさんに、お礼なのか挑発なのか分からないツイートをして

私のセッションに来て頂きました。我ながら、強引なことをしたもんです。


そんなわけで、夜には自分のセッションがあったわけですが

それについては、前後の話も含めて、またきちんと別エントリとして投稿します。


Day 4 - Lambda、Lambda、JFR

おはよう世界。

自分のセッションが終わった開放感からか、倒れ込むように寝てしまい

これは昼まで寝るかなと思ったら、意外と5時間睡眠ぐらいで目が覚めてしまい

時差ボケの威力を実感した早朝でした。


そんなわけで、朝から元気にセッションに参加します。

そう、僕のJavaOne参加はここから始まったわけです。


[CON2055] Programming with Lambda Expressions in Java

Agile Developer, Inc.の社長、Venkat Subramaniamによる

軽妙でウィットに溢れたLambdaのセッションでした。


内容的には、外部イテレーターから内部イテレーターの書き方の移り変わり、

Lambdaの文法やstreamの使い方や効果などを紹介するという

比較的、初級者向けのセッションなのですが、その語り口調が面白すぎて

本当に笑いの絶えないセッションでした。


直接的な表現よりも、間接的な表現を軽妙に語る事で面白さを増す感じでしたね、たとえば

  • 汚い → とても子供に見せられない。しっ見ちゃいけません!
  • 危険 → 何をやろうとしているんだ、家に帰って考え直せ!
  • 素敵 → これは食欲をそそる!

などなど。

って私はJavaOneに来て何を学んでるんですかね。


もう少し実用的なところをフィードバックすると、

やはりLambda時代にはAPIデザインが少し変わるということでしょうか。


たとえば自分で比較するユーティリティメソッドを書く際には、

isPriceLessThan(500, value) と書けるようなAPIを提供するのではなく、

isPriceLessThan(500).test(value) と書けるようなAPIを提供することで

Lambda式として利用できるようにしていました。


ちょっとこの辺り、自分でも消化しきれていないので

日本に帰ったら資料を見ながら復習しようと思います。


ってよく考えたら、このセッション

テキストエディタだけで話してたから、資料ないんだった (^^;;


[CON7942] Java 8 Streams: Lambda in Top Gear

続けてのLambdaセッション

Paul Sandozと、Lambdaの神Brian Goetzのセッションです。


streamのAPIは、集計処理などにおいて、

うまくparallel化ができるもの、できないものがあったり、

処理を途中で中断しても良いもの、全ての要素を走査するものがあるなど、

APIは、いくつかのカテゴリで「分類」することができます。


この分類次第で、parallel化した時のパフォーマンスなども変わってくるため

streamを使う際には、この分類をきちんと押さえておかなければいけない、

ということが説明されていました。ちょっと自分にはなかった視点でした。


この辺りは、資料をダウンロードして学び直す必要があるので、

ボロが出ないうちに、説明をこの辺で切り上げましょう (^^;


[CON5091] Java Flight Recorder Behind the Scenes

3日の朝イチに解析ツールの紹介していた、Staffan Larsenのセッション

前半こそFlight Recorderの紹介だったのですが、

後半はFlight Recorderの設計の話が展開され、かなり興味深かったですね。

そんな後半の話だけピックアップして紹介します。


1. Thread buffers

Flight Recorderが取得した情報は、スレッドローカルのThread buffersに貯めてから、

共有のGlobal buffersに書き出します。

こうすることで、Global buffersへの書き込みが衝突することを抑えています。

この辺りは、Flight Recorderがメイン処理に影響を与えないようにするために

欠かせない、いわば当たり前の設計でしょう。


2. Flight Recorderは永久には情報を取り続けない。

メモリリークへの対策として、情報は一定期間かサイズごとに消すか上書きしています。

これも当たり前のことですが、私は過去にちょっとやらかした事があります (^^;


3. Flight Recorderは、アプリケーションのクラスやオブジェクトへの参照を持たない。

これも、メモリリークを防ぐうえで不可欠のポリシーです。


4. クラス名はIDに変換する。

クラス名(文字列)を、int程度の数値に変換することで、

ファイルやメモリの空間効率を向上させます。

また、そのクラス名と数値のマップをFlight Recorderの出力ファイルに

持たせておくことで、互換性や移植性にも配慮しています。

こういう細かいところも、きちんと工夫しているんですね。


5. クラス一覧自体も定期的にリセットする。

クラス一覧がメモリリークの原因にならないよう、

一定期間ごとにファイルに出力して、クラス一覧をクリアしてしまいます。

(このタイミングを「チェックポイント」と読んでいました)

最後にクラス一覧をマージするかどうかは、ちょっと分かりませんでした。

マージしないと重複が出てしまって、ファイル効率がよくない気がします。


6. スタックトレースのpoolを作る。

同じスタックトレースが何度も表れることが多いため、

スタックトレースのプールを作っておいて、(全く)同じスタックトレース

発生した場合には、前のスタックトレースへの参照を使うだけにします。

なるほど、勉強になります。


というような、ENdoSnipeの開発者的にありがたい情報がたくさんありました。

もちろんアプリケーション開発をするうえでも、このようなメモリやデータの

効率化の仕組みを「発想」することは、とても大切だと思います。

まだまだやるべき事があるのだなと、改めて思い知らされた感じです。


[CON2959] Modular JavaScript

Luminis Technologies社のSander Mak、Paul Bakkerのセッション

なんかJavaとの連携もありそうな感じのアジェンダが提示されていたんですが

実際には、JavaScriptのライブラリやフレームワークを使ったときの

packageやclassの可視性なんかを、延々延々とJavaScriptのソースで説明するセッションで、

Javaコードは全く出てきませんでした。


ここJavaOneやぞ!


4日目終わり

この後の時間帯に、kotlinのセッションがあったり、

あの #てらだよしお さんのJavaEEのセッションがあったのですが、

どうしても眠かったため、ホテルに戻って休んでいました。


聞くところによると、kotlinのセッションは10人いなかったそうです。

kotlinの過疎感ハンパない!(><)


そして寺田さんのセッションは「質問はTwitterでお願い」と言っていたにも関わらず、

バンバン質問が出て、大変だったそうです(そして、きちんと回答したそうです!)

そりゃOracleのエンジニアがJavaEEについて話したら、質問出るって!


ちなみに4日目の夜には、トレジャーアイランドで

Maroon5というバンドのライブなどあったのですが、

上にも書いた通り、ホテルに戻ってお休みしていました。


Folder5が来るんだったら、無理してでも行ったと思うんですけどね。

#行かねーよ。


そんなわけで、JavaOneも後半戦に差し掛かってきました。

2012-12-06

[]ITエンジニアの英語の接し方

エンジニアもすなるAdvent Calendarといふものを俺様もしてみむとてするなり

と言ったかどうか分かりませんが、自社の後輩が始めた全く流行らないAdvent Calendar、

ちょっと私も責任を感じて書いてみることにしました。


新人/若手向け、これだけは知っとけTips25 Advent Calendar 2012

http://www.adventar.org/calendars/37


さて、このエントリーのテーマは「ITエンジニアの英語の接し方」です。

なんだかんだ海外発の情報が多い業界ですので、英語ができれば得られる情報も人脈も広がります。

この業界に入ったけども「英語が苦手で、ちょっと何とかしたい」と思っている人向けに書いてみます。

マジレスすると、DUO 3.0

先に真面目な話を書いておきますと、集中して英語を勉強する気持ちがあるなら、

みんな大好き「DUO 3.0」をマスターするのが手っ取り早いでしょう。

DUO 3.0

DUO 3.0

DUO 3.0は例文の構成が上手く、中級レベルの単語がきちんと網羅されていますし、

時事ネタにも使えそうな表現や人間の感情などがよく入っており、

繰り返し聞く事が苦にならないのが良い所です。


DUO 3.0の書籍と基礎用CDを買って数回聞いて内容を把握したうえで、

復習用CDを100〜200回ぐらい繰り返して聞いて暗記すれば、

それだけでTOEICで言うところの600〜700点レベルにはなるんじゃないかなと思います。

DUO 3.0 / CD基礎用

DUO 3.0 / CD基礎用

DUO 3.0 / CD復習用

DUO 3.0 / CD復習用


まぁこんな真面目な話は割とどうでも良くて、ここから先は

普段の生活を少しずつ英語化して、英語に接する機会を増やすための方法を紹介しますね。

海外セミナーに行きやがれ!

ITエンジニアなら、やっぱり行きたい海外セミナー。


Javaが好きな私は、みんな大好き「JavaOne」によく行くわけですが、それ以外にも、

Googleの技術が好きならGoogle I/O ( https://developers.google.com/events/io/ )

Apple信者ならWWDC ( https://developer.apple.com/wwdc/ )

Microsoft派ならMIX ( http://www.microsoft.com/events/mix/ )

AWSにハマっているならre:Invent ( https://reinvent.awsevents.com/ )

HadoopでビジネスするならHadoop World ( http://www.hadoopworld.com/ )

Flash/Flexから離れられない方はAdobe MAX ( http://max.adobe.com/ )

など、選択肢を挙げればキリがありません。


たとえ英語力、技術力ともにあまり自信がなかったとしても

このようなイベントに参加すると、それだけで確実に英語・技術とも「もっと勉強しよう!」という

強力なモチベーションになるんですよね。


また、毎年参加していると、少しずつ理解できることが増えていくので

自分の英語力・技術力の成長を実感できますよ!

Huluで海外ドラマを英語字幕で観やがれ!

カンファレンスなどまだ早い、まずは日本でのお勉強だ、という向きの方には

海外のドラマや映画を見るのが手っ取り早いですよね。

と言っても海外映画を字幕なしで観るとか、まぁ正味の話、無理ですよね。

映画を楽しめないどころか、ストーリーすらよく分からないレベルなので、まず長続きしません。


そこから一段階レベルを下げたのが「英語字幕つきの海外ドラマや映画」です。

英語を十分には聞き取れずとも、字幕の助けもあって理解できることが多いです。


英語字幕つきのドラマを見たいならDVDやBlu-rayを借りれば良いのですが、

TSUTAYAに借りに行くのも面倒ですし、ここはITエンジニアらしく、

動画配信サービスの「Hulu」などに手を伸ばしましょう ( http://www.hulu.jp/ )


Huluは海外ドラマや映画を英語字幕つきで観られる数少ないサービスです。

(もちろん日本語音声や日本語字幕でも観られますよ!)

PCだけでなく、iPhoneやAndroid、WiiやPS3など対応デバイスが多く、

月額980円と値段も控え目なのが良い所ですね。若干、UIが使いにくい所がありますが。


Huluを使って、みんな大好き「24」や「プリズンブレイク」を英語字幕で観ていれば

楽しんでいるうちに英語が入ってきますよ!

ディスカバリーチャンネルを流し見やがれ!

ドラマや映画は割と気合いを入れて観ないとストーリーが分からなくなるので、

ちょっとしんどいかも知れません。

そんなドラマに比べて気軽に観られるのが、いわゆるドキュメンタリー番組。


特にサイエンスが好きなITエンジニアにオススメなのが「ディスカバリーチャンネル」ですね。

スカパーやケーブルテレビ、あるいは、ひかりTVあたりを適当に契約して

ネットでもしながらディスカバリーチャンネルを英語音声で流しっぱなしにしておくと

いい感じに英語が耳に入ってくるでしょう。


日本でも時々取り上げられることがある、怪しい伝説 (MythBusters) などの番組も

ディスカバリーチャンネルで放送していますよ!

Kindleで洋書を読みやがれ!

映画やテレビの英語のスピードには着いて行けない・・・というなら、洋書はどうでしょうか。


、、、なんて言うと「英語は別に読めるんですよ。でも、聞き取れないんですよ」と

反論したくなるかも知れませんが、以前、どこかの英語教育サイトで、

「英語を聞き取れないのは、読むのが遅いからだ」という論を見たことがあります。


つまり「英語を読むスピードが、通常会話のスピードよりも遅い」ような英語レベルでは

当然、話す英語なんて理解できるはずがない、という論です。分からなくはない話ですよね。


そんなわけで、洋書を読んでみたいと思ったのなら、Kindleがオススメです。

Kindleは英単語をタップするだけで辞書が開くので、別に辞書を用意しなくて良いのが嬉しいところです。

辞書は英和辞書、英英辞書のどちらもあるので、自分のレベルに合わせて切り替えれば良いでしょう。

別にKindleデバイスでなくとも、iPhone/iPad/AndroidのKindleアプリにも同じ機能がありますよ。


オススメの洋書は、別にハリーポッターなどでも良いのですが、

やはりITエンジニアであれば、みんな大好き「Steve Jobs」がオススメです。

STEVE JOBS

STEVE JOBS

意外と文法も単語も平易で、読みやすかったりしますよ!

英語でゲームをやりやがれ!

本を読む習慣すらない怠惰な人には、もうゲームをオススメするしかないですね。

IT業界にいるということは、割とゲームとかやってたタイプですよね?


iPhoneやAndroid向けのゲームアプリには海外発の英語アプリも多いですし

日本製のアプリであっても、英語モードが用意されていたりします。


みんな大好き「ファイナルファンタジーシリーズ」などは、メッセージを英語にすると

海賊は汚い言葉を使うし、地方の人は言葉が訛っているし、老人は偉そうだったりで、

日本語版に比べて、かなり表現が豊かになっていますよ!

OSは英語モードにしやがれ!

ゲームする時間もないなら、もう普段の環境を英語モードにするしかありません。

PCやスマートフォンをすべて英語モードにしておくだけで、IT英語に触れられます。

最近のOSなら、設定を変えるだけで(Windows7は言語パックをダウンロードすれば)

英語化することができます。


あと、海外製の開発環境やツールなども、わざわざ日本語化せずに英語のまま使うようにしましょう。

みんな大好き「Eclipse」なんかも、Pleiadesを使ったりせずに、英語版のまま使えば良いんです。


あとOfficeやセキュリティソフトなどの有償ソフトウェアなんかも、

海外サイトでダウンロード購入すると、円高の昨今、ちょっと安かったりしてお得ですよ!

まとめ

みんな大好き「DUO 3.0」を100回ぐらい聞きやがれ!

みんな大好き「JavaOne」に参加しやがれ!

みんな大好き「24」や「プリズンブレイク」をHuluで英語字幕つきにして観やがれ!

みんな大好き「ディスカバリーチャンネル」を流し見しやがれ!

みんな大好き「Steve Jobs」をKindleで読みやがれ!

みんな大好き「ファイナルファンタジー」を英語メッセージにしてプレイしやがれ!

みんな大好き「Eclipse」は英語のまま使いやがれ!


ちなみに「みんな」というのは、全部、私のことなんですけどね!

そんなわけで、私がやってる英語への接し方を紹介しました m(_ _)m

一つでも参考になって実践してもらえれば、幸いです!