Blogフリュー株式会社の技術ブログです2016年10月28日Vue.jsを使ってみようJavaScriptこんばんは、フリューのジョンです。普段はサイト開発をしており、最近Mithril.jsからVue.jsに移行しています。今回はVue.jsのお話です。JavaScriptのフレームワークっていっぱい聞くけどどういうところが嬉しいんだろう、というレベルの方にお伝えしたいと思います。概要Vue.jsはReact.jsやAngular.jsと同じようにMV*系のフレームワークです。近年はJavaScriptのフレームワークは飽和していますが(React.js、Angular.js、Riot.js、Aurora.jsなどなど)それではなぜそのようなフレームワークを使うのでしょうか?jQueryじゃダメなのでしょうか?いえ、jQueryでもできます。既存のフレームワークのほうが楽をすることができる可能性が高いです。view周りをフレームワークに任せることができるので、logicに集中できる。jQueryのみで大きなページを作成すると、logicとview部分が複雑になる。要素をJavaScriptで作成している複雑なページは、仮想DOMを使用しているフレームワークを使うと、描画速度が早くなる一つ目の利点について考えてみます。value="3">コンテンツCを表示する</option></select></section>おそらく、コード量を抑えるとしたら以下のように書くと思われます。他を消してから、選択されたものを表示するということになると思います。contentNumber).show();});})では、少し意地悪な変更が加えられたとしましょう。現状idを使って選択していますが、このidは一般的すぎて変更したいですね。その場合、JavaScript側のセレクタも変更しなければいけません。それに加え、optionタグのvalueを使って切り替えられると思っていたlogicの前提が崩れてしまいます。*1フレームワークを使うと、このような画面切り替えなどもフレームワーク側が対応してくれるのです。(後にこの問題をVue.jsではどう記述するかを説明します)そこでVue.jsですでは他のフレームワークではなく、Vue.jsを使う利点はなんでしょうか?私としては、以下だと考えられますviewをhtmlに書くことができるので、viewを分業しているプロダクトではデザイナさんが変更しやすいAngular.jsでも同じようなことができるのでは?となりますがVue.jsではよりデザイナさんが理解しやすいhtmlの書き方になっています。軽量な画面に関しては、少量のコード量で済みます。仮想DOMを用いているため描画スピードも早いです。Vue.jsを使ってみよう先ほどのselectタグの値によってコンテンツの表示切り替えを行いたい場合を題材にします。value="3">コンテンツCを表示する</option></select></section>各コンテンツにidを書かないようになりました。その代わりにv-showという表示、非表示を切り替える際に使う「ディレクティブ」をつけています。selectタグにもidを書いていません。その代わりにv-modelという双方向のデータバインディングを行うディレクティブをつけています。1}});}JavaScript側では、Vueに、rootとなるタグのセレクタと他のデータを渡しています。Vueのコンストラクタに渡したオブジェクトにあるdataにはcontentが1で入っています。これがselectタグに渡り、どのoptionタグを表示するかを決めています。selectタグのonchangeイベントが走るとoptionタグのvalueがcontentに入ります。contentの値が変化すると、各コンテンツに書いてあるv-showの評価が行われます。その評価値がtrueになった場合、そのコンテンツが表示されるという仕組みになっています。?idの変更やデザインの変更がある場合もこれならば影響はありません。まとめjQueryだけでもできるページは少なくありませんし、広く一般的になっていると思われます。複雑度が増してくると、途端にコード量が増えていきます。これまでの例からもVue.jsはかんたんに導入できることがわかりましたので、何か面倒だなと感じたときには、ぜひライブラリやフレームワークを使ってみてください。次はVue.jsを使った少し複雑な例をお送りしたいと思います。おまけ今回のソースコードについてはjsfiddleにあげておりますのでご確認ください。data属性を使うなど回避策はありますが、ここではわかりやすいようにしています。コンテンツ・メディア第1事業部のjyukutyoこと阪田です。前回はコレクションのセッションについてのレポートでした。今回はクラスローダーのセッションについてレポートします。Leaksスライドはこちらにあります。https://static.rainfocus.com/oracle/oow16/sess/1461358415846001E0TZ/ppt/Classloader%20leaks%20public.pptx内容java.lang.OutOfMemoryError(OOME)はみな出会ったことがあるだろう。spaceとは出なくなったが、代わりにMetaspaceが出るようになった。ローカルでの開発時にも、継続的デプロイでもOOMEは出る。このセッションのアジェンダは次のようなものだ。OOMEは何を意味するのか?OOMEはなぜ起こるのか?どこでリークするのか?どのように避けるのか?OSSの例トレーニングOOMEは何を意味するのか?JVMのメモリはヒープとPermGen/Metaspaceとスタックである。スタックはスレッドごと、ローカル変数やメソッドのパラメータを持つ。ヒープはオブジェクトのインスタンスを持つ。PermGen/Metaspaceはjava.lang.Classインスタンスなどを持つ。EEとクラスのアンロードができる前に名付けられた。8でMetaspaceへ置き換えられた。space/Metaspaceは、あまりに多くのクラスをロードしたときに起こる。space/Metaspaceが起こる原因は次の2つが考えられる。アプリケーションが大きすぎる。7までは-XX:MaxPermSize=256Mなどと指定すればよい。8ではMetaspaceは自動的に増えていく。java.lang.Classインスタンスが再デプロイ後にガベージコレクトされない参照の型は次の4つがある。強い参照:到達可能なときは決してGCされないソフト参照:OOMEになる前にGCされる弱い参照(WeakHashMap):強い参照とソフト参照がないときにGCされるファントム参照:GCは妨げないGCの到達可能性は以下の図のようなことである。再デプロイでは、新しいWARファイルをデプロイすれば前のクラスローダはGCされる。クラスローダーの参照は次の図のようになる。どのようにリークが起きるのか。GCルートからクラスローダへ到達可能だと、クラスローダをGCすることができない。どこでリークするのか?Tomcatなどアプリケーションサーバのバグだ。Languageのバグといったこともある。GCルートでも起こる。システムクラスローダによってロードされるクラス。JDKのクラスにおけるstaticフィールドで起こる。ライブスレッドではローカル変数、メソッドのパラメータのスタック、java.lang.Threadインスタンスで起こる。introspectionのキャッシュ、シャットダウンフック、カスタムでデフォルトにしたAuthenticator、カスタムのセキュリティでのProvider、カスタムMBean、カスタムのThreadGroup、カスタムのプロパティエディタ...最初の呼び出し元でのcontextClassLoaderへの参照などで起こる。DriverManagerをもう少し詳しく見てみよう。MySQLのJDBCドライバを使うときはこうするだろう。Class.forName("com.mysql.jdbc.Driver");1Class.forName("com.mysql.jdbc.Driver");com.mysql.jdbc.Driverクラスにはstaticイニシャライザがある。driver!");}}registerDriver()メソッドは以下のようになっている。da));...このregisterDriversという変数は、以下のものだ。CopyOnWriteArrayList<>();図で表すと以下のようになる。そのため、コンテキストのシャットダウンで以下のように書かなければ、リークしてしまう。{DriverManager.deregisterDriver(...);}}スレッドもここで止めておかなければならない。次のようにスレッドを実装するのは悪いアイデアだ。something}}}止められるようには以下のようにする。false;}}このことは、次の記事に紹介されている。Spot次にThreadLocalについて考えてみよう。次のように実装してはならない。ThreadLocalのJavaDocには以下のようにある。...各スレッドは、スレッドが生存していてThreadLocalインスタンスがアクセス可能である間は、スレッド・ローカル変数のコピーへの暗黙的な参照を保持します。プールされたスレッドではスレッドはクラスローダより長生きする。ThreadLocalはThreadGlobalになる!ThreadLocalMapのJavaDocには以下のようにある。space(私訳)しかしながらリファレンスキューが使われないので、テーブルが容量不足になり始めたときだけ失効したエントリが削除されることが保証されます。参照を含んだカスタムの値は、staticなThreadLocalであればリークし、そうでなければ予測されていないGCとなる。カスタムのThreadLocalであればリークしない。ThreadLocalはクリアするようにしよう。{myThreadLocal.remove();}実際には、多くのOSSライブラリが違反している。どのように避けるのか?リーク防止のライブラリがある。実行時の依存は0で、設定は必要ない。Mavenであれば以下のように依存ライブラリを追加する。3.0以降用だが、2系のものもある。Validationの1.0.0.GAでは以下のようになっていた。List<ValidationProvider<?>>>();(私訳)List<ValidationProvider>はキーであるクラスローダに強い参照を持っている。JPAのCachingPersistenceProviderResolverと同じモデルを使うようにして。Validationの1.1.0.GAではこのクラスは次のようになっています。);とあるので、ソフト参照を使うようになったようです。JPAのCachingPersistenceProviderResolverクラスも調べてみました。PersistenceProvider>>>();その他のOSSjavax.el.BeanELResolverやorg.apache.cxf.transport.http.CXFAuthenticator、com.sun.star.lib.util.AsynchronousFinalizerも該当する。Analyzer(MAT)を使おう。http://www.eclipse.org/mat/次のオプションをつけてアプリケーションを実行しよう。最後に出てきた、MATについてはこのブログで私が記事を書いています。Analyzerで解析しよう!セッションとしては非常におもしろかったです。OSSの実例を挙げながらリークの原因を解説する箇所ではとても興奮しました。いう内容のセッションはJavaOneだと他にもいろいろとあります。コンテンツ・メディア第1事業部のjyukutyoこと阪田です。2とGWTのチュートリアルセッションをレポートしました。Refueled”をレポートします。Refueledスライドはこちらにあります。https://stuartmarks.files.wordpress.com/2016/09/collectionsrefueled-final.pdfタイトルの通り、Javaのコレクションフレームワークについての話です。9での拡張と将来の作業についてでした。1.0はレガシーコレクション、VectorやHashtableなどである。1.2はコレクションフレームワークが導入された。インタフェースとしてCollection、List、Set、Map、Iteratorが、具象クラスとしてArrayList、HashSet、HashMap、TreeSet、TreeMapがある。5.0ではジェネリクス、java.util.concurrentパッケージが追加された。8ではラムダとストリームが追加され、インタフェースにデフォルトメソッドとstaticメソッドが定義できるようになった。15年経って初めての変更だ。8list.forEach(System.out::println);CollectionはIterableのサブインタフェースなので、これはすべてのコレクションで動作する。Iteratorインタフェースでは、ほとんどのイテレータは削除をサポートしていない。そのためこう書く必要があった。UnsupportedOperationException();}remove()のデフォルトメソッドがまさにこれだ。削除できないイテレータを作るときは、単にremove()を省くだけでよい。削除できるものを書くときは、remove()メソッドをオーバーライドするだけだ。Collectionインタフェースでは、removeIfでバルク更新ができるようになった。str.startsWith("A"));もしコレクションがArrayListなら、7の場合の計算量はO(n^2)であり、8の場合はO(n)となる。ListListインタフェースのreplaceAllもバルク処理だ。8list.replaceAll(String::toUpperCase);ただし、要素の型を変更することはできない。したいときはStreamを使う。List.sortはCollections.sortよりなぜよいのか?Collections.sortは3つのステップを使う。一時的な配列にコピーする配列をソートするリストにコピーして戻すList.sortはデフォルトでは上記と同じだが、ArrayList.sortはオーバーライドしてin-placeでソートするため、コピーはしない。Collections.sortは現在単にList.sortを呼び出すだけだ。MapMapインタフェースにもforEachがある。v));replaceAllもある。7までMulti-mapはとても扱いづらかった。Multi-mapはキーに対して複数の値があるマップだ。values()multimap.values().stream().flatMap(Set::stream);ComparatorComparatorを書いて楽しい人はいる?Comparatorは多くの条件とコードの繰り返しだ。8はComparatorにstaticとデフォルトメソッドを追加した。名字とnullがある名前でソートし、nullを最初に持ってくる2レベルのソートのサンプルを見てみよう。