kagamihogeの日記

kagamihogeの日記です。

JEP 307: Parallel Full GC for G1をテキトーに訳した

http://openjdk.java.net/jeps/307 をテキトーに訳した。

JEP 307: Parallel Full GC for G1

Owner    Stefan Johansson
Created 2017/01/17 11:40
Updated 2017/11/13 16:52
Type    Feature
Status  Targeted
Component   hotspot?/?gc
Scope   Implementation
Discussion  hotspot dash gc dash dev at openjdk dot java dot net
Effort  M
Duration    M
Priority    3
Reviewed by Mikael Vidstedt
Endorsed by Mikael Vidstedt
Release 10
Issue   8172890

Summary

G1のワーストケースのレイテンシ改善のため、パラレルのフルGCを導入します。

Non-Goals

すべてのユースケースにおけるパラレルGCのフルGCのパフォーマンス調整。

Motivation

G1 GCJDK 9のデフォルトになりました。以前のデフォルトのパラレルGCには、パラレルフルGCがあります。ユーザが直面するフルGCインパクトを最小化するため、G1フルGCもパラレルに出来るのが望ましいです。

Description

G1 GCはフルGCを避けるように設計されていますが、コンカレントコレクションが速やかにメモリを回収出来ない場合はフルGCにフォールバックします。G1 GCの現在の実装はシングルスレッドのmark-sweep-compactアルゴリズムです。我々はmark-sweep-compactアルゴリズムをパラレル化し、また、YoungとMixedのコレクションに同じ数のスレッドを使うようにしよう、と考えています。スレッド数は-XX:ParallelGCThreadsオプションで制御可能にしますが、YoungとMixedコレクションに使われるスレッド数にも影響します。

Testing

  • フルGC時間の改善を確認するためにその時間を分析します。G1はフルGCを避けるよう設計されているので、ベンチマークスコアの確認ではおそらく不十分です。
  • ボトルネックを見つけ出すのにVTuneもしくはSolaris Studio Performance Analyzerを使用したランタイム分析をします。

Risks and Assumptions

  • G1の基本設計がパラレルフルGCを阻害しないという仮定の上にこのJEPは立っています。
  • G1にはリージョンがあるので、単一スレッドのフルGCよりもパラレルフルGC後の方が余計にメモリを浪費する可能性がかなり高いです。

Spring Bootをeclipseのdynamic web projectとして実行する

spirng-bootには組み込みコンテナがあるので、開発時にアプリケーションサーバ上で動かしたいケースはアンマリ無いが、一応メモ。といっても、jarからwarに変更する際の手順をやればよいだけ。参照:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file

まず、プロジェクト右クリック -> config -> Converted to faceted formでDynamic Web Moduleにチェックを入れて、プロジェクトをdynamic web project扱いにする。

従来のspring-mvcとかではWebApplicationInitializerのサブクラスを自前で作ったりしていたが、それのspring-boot版のSpringBootServletInitializerを継承したクラスを作る。リファレンスのサンプルではspring-bootのmain置いてるクラスに継承させているが、役割的に同じだからなのだろう。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);

    }

}

pom.xmlのpackagingをjarからwarに修正する。

 <packaging>war</packaging>

このまま起動すると、tomcatの組み込みコンテナが邪魔してAPサーバが起動しない。ので、その依存性をprovidedにする。

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

これで起動する。動作確認はwildfly 10で行った。

Difference between @RestController and @Controller Annotation in Spring MVC and RESTをテキトーに訳した

http://javarevisited.blogspot.jp/2017/08/difference-between-restcontroller-and-controller-annotations-spring-mvc-rest.html を読んだ。実はspringよく知らずに使っている。

Difference between @RestController and @Controller Annotation in Spring MVC and REST

Spring MVC@RestControllerアノテーション@Controller@ResponseBodyを組み合わせたものです。子のアノテーションはSpring 4.0で追加されたもので、RESTfulなWebサービスの開発をしやすくするためのものです。REST web servicesを既に知っているのであれば、webアプリケーションとREST APIの違いについても知っているかと思います。前者のwebアプリケーションのレスポンスは基本的にはビュー(HTML + CSS + JavaScript)である一方、後者のREST APIJSONXML形式のデータのみ返します。これらの相違点は@Controller@RestControllerでも同様です。@Controllerの役割はモデルオブジェクトのMapの生成とビューの参照で、@RestControllerは単にオブジェクトを返し、オブジェクトデータはHTTPレスポンスにJSONXML形式で直接書き込まれます。

これまで通りのやり方である@Controller@ResponseBodyで同じことが出来ますが、この動作はRESTful Webサービスのデフォルトの振る舞いです。そのため、Springは@Controller@ResponseBodyの振る舞いを組み合わせた@RestControllerを導入しました。

つまり、以下の二つのコードはSpring MVCでは等価です。

@Controller
@ResponseBody
public class MVCController { 
   .. your logic
}
@RestController
public class RestFulController { 
  .... your logic
}

当然ながら、アノテーションを2個よりも1個の方が好まれます。また、@RestControllerの方が意図が明瞭です。

What are @Controller and @RestController in Spring?

Springフレームワークでは、Controllerのクラスはビューで表示するデータをモデルMapを構築すると共に正しいビューを選択する役割を担います。なお、@ResponseBodyアノテーションでレスポンスのストリームに直接書き込んでリクエストを完了することも可能です。

レスポンスストリームに直接書き込む動作はRESTful Webサービス呼び出しに対する責務にマッチしており、この場合は以前のエントリhow Spring MVC works internallyで述べたようにビューを返す代わりにデータを返したいからです。

Spring 3もしくはSpring 3.1などSpring 4以前でRESTful Webサービスを開発していた場合、RESTfulなレスポンスの生成に@Controller@ResponseBodyの組み合わせを使用していたかと思われます。Springの開発者はこの課題を認識していたので@RestControllerを作成しました。

よって@Controller@RestponseBodyを使う必要は無くなり、同様なことを実現するには@RestControllerを使えば良くなりました。つまり、このアノテーション@Controler@Responseボディの振る舞いを一つにまとめた簡易化コントローラー、ということです。

SpringのRESTFul Webサービスの高度なテクニックに関心があればEugen Paraschiv氏のREST with Spring Master classを購入してみてください。

Difference between @RestController and @Controller in Spring

@RestController@Controlerアノテーションを既に使ったことがあるのであれば、両者の違いを見ておくと良いです。採用面接の点ではなくSpring CoreおよびSpring Web Application developer Certificationの点で重要です。Spring certificationsを受ける場合、これらの微妙な違いを知っておくと良いです。また、フリーのSpringテストで試験形式と問題のレベルを見ておくのも良いでしょう。

ともあれ相違点の話に戻ると、両アノテーションには大きな違いがあります。

1.@ControllerはSpring MVCのContollerとしてクラスを作成するための一般的なアノテーションですが、@RestControllerRESTFul web servicesのための専用コントローラーで@Controller + @ResponseBodyと等価です。

2.@RestControllerは比較的新しいもので、Spring 4.0から追加されたものですが@ControllerはSpringがアノテーションをサポートし始めた古くから存在するもので、正式にはSpring 2.5バージョンから追加されています。

3.@Controllerはそのクラスが"Controller"、例えばwebコントローラー、であることを示す一方、@RestControllerはそのクラスが、@RequestMappingのメソッドがデフォルトで@ResponseBodyを返すと想定されるコントローラ、つまりREST API、を示します。

4.@Controller@Componentを専用化したもので、@RestController@Controllerを専用化したものです。実際には以下のように@Controller@ResponseBodyによる簡易化コントローラーとなっています。

@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController

@Controllerの宣言は以下のようになっています。

@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Component
public @interface Controller

5.Spring MVC@Controler@RestCotrollerの主要な相違の一つは、クラスに@RestControllerを付与するとそのすべてのメソッドはビューではなくドメインオブジェクトが書き込まれます*1。Springベースのアプリケーションで@RestControllerを使う方法のより詳しい方法についてはBryan Hassen氏のIntroduction to Spring MVC 4を参照してください。

6.@Controler@RestCotrollerのもう一つの違いは、以下のように@RestControllerをクラスに付与する場合はすべてのハンドラメソッドに@ResponseBodyを付ける必要が無い点です。

with @RestControler

@RestController
public class Book{

@RequestMapping(value={"/book"})
public Book getBook(){
//...
return book;
}
}

without @RestController

@Controller
public class Book{

@RequestMapping(value={"/book"})
@ResponseBody
public Book getBook(){
//...
return book;
}
}

RESTful responseを作成するのにSpring MVC@Controllerを使うと分かるのですが、個々のメソッドに@ResponseBodyを付ける必要があり、@RestControllerではその必要がありません。読みやすさは元よりキーを押す回数も減らせます。

SpringBoot@RestControllerで作成したHelloWorldサンプルは以下になります。

画像:http://javarevisited.blogspot.jp/2017/08/difference-between-restcontroller-and-controller-annotations-spring-mvc-rest.html#axzz4spOd15rP

以上がSpring MVC@Controller@RestControllerの違いになります。@RestControllerは単に@Controllerと@ResponseBodyを組み合わせたものです。

SpringフレームワークでRESTfulなwebサービスを作りやすくする意図で、Spring 4でこのアノテーションは追加されました。リクエストのMIMEタイプに応じてレスポンスをJSONXMLに直接変換します。

このため、 RESTful Web Servicesを作るには@Controller@ResponseBodyを付けるよりも@RestControllerを使う方が良いです。

SpringとSpring SecurityフレームワークでRESTful Web Servicesを開発する場合の詳細を学ぶには、Eugen Paraschiv氏のREST with Spring Coaching classの購入を推奨します。EugenはJavaでのセキュアなRESTful webサービスと実際の開発経験を持っているので、この教材は彼の経験から得られた知識を学ぶには良い機会となっています。

*1: then every method is written a domain object instead of a view. REST APIとしてメソッドを公開すると、役割が変わってくるよーという意味合いと思われるが、なんかヘンな訳。