SlideShare a Scribd company logo
1 of 43
Download to read offline
GCは、ガベージコレクションの略で、日本語だ
と、ごみ収集の意味ですね。
で、コンピューター業界で言う、ごみ収集とい
うのは、ずばり、メモリのごみ掃除屋さんを示
します。
メモリ
GCとか、勉強する価値あるの?
考えなくて良いために、GCあるんちゃうん?
はい、例えばJavaで、頼まれた設計書の内容を
ただ記述するだけのコーダーのような人には必
要ないでしょう。
ただ、もし、Javaプログラマーとして、ご飯を
食べて生きたいと思っているなら、ちょっと
待って欲しい。
プロのJavaプログラマとして、
GCすら知らない!!
まして、GCに対するチューニングも、問題発生
時の対処も出来ないというのは、Javaプログラ
マと果たして、言えるのでしょうか?
いや、言えない!!
私の感覚だと、プロジェクト3つくらいやれば、
1つくらい、GCの問題にぶち当たってるイメージ
です。
また、C# の話とはなりますが、最近チラッとみ
た、優秀なエンジニアたちの呟きをご覧くださ
い。
このように、優秀なエンジニアは、
GCを制す必要があるのです!!
GCを制すものはJavaを制す!!
GCの必要性について、わかったところで、
引き続き、素晴らしきGCの世界を
勉強していきましょう!
C言語でのメモリの利用について見てみよう。
char *str;
/* 文字列のためのメモリを確保 */
Str = (char *)malloc(100);
/* 文字列を入力(abc) */
gets(str);
/* 文字列の表示 */
puts(str);
/* メモリの解放 */
free(str);
C言語でのメモリの利用について見てみよう。
char *str;
/* 文字列のためのメモリを確保 */
Str = (char *)malloc(100);
/* 文字列を入力(abc) */
gets(str);
/* 文字列の表示 */
puts(str);
/* メモリの解放 */
free(str);
メモリ
サイズ:100
内容:空
C言語でのメモリの利用について見てみよう。
char *str;
/* 文字列のためのメモリを確保 */
Str = (char *)malloc(100);
/* 文字列を入力(abc) */
gets(str);
/* 文字列の表示 */
puts(str);
/* メモリの解放 */
free(str);
メモリ
サイズ:100
内容:空
メモリ
サイズ:100
内容:abc
C言語でのメモリの利用について見てみよう。
char *str;
/* 文字列のためのメモリを確保 */
Str = (char *)malloc(100);
/* 文字列を入力(abc) */
gets(str);
/* 文字列の表示 */
puts(str);
/* メモリの解放 */
free(str);
メモリ
サイズ:100
内容:空
メモリ
サイズ:100
内容:abc
メモリ
サイズ:100
abc
というわけで、C言語など、GCのない世界では、
自前で、メモリの管理を行っていた。
これによって、C言語er の人たちは日々、以下
の問題を抱えていた。
・メモリリーク (メモリ解放忘れ)
・メモリの二重解放 (掃除のやりすぎ)
・メモリアクセス違反 (メモリ管理大失敗)
そこで、GCですよ!!!
メモリ
GCさえあれば、もう、
面倒なメモリ管理から
今すぐ解放!!
致命的な不具合とも
おさらば!!
金運も上昇!!!
ツイて、ツイて、
ツキまくーる!!!!
メモリ
※効果には個人差があります
では、やっとこさ、そろそろ本題となる、
GCは一体どんなお仕事をしているのか??
・・・、というのを
Javaを用いて、順に見ていこう!
// 人間クラス
class Human {
int hp;
int mp;
public Human(int hp, int mp) {
this.hp = hp;
this.mp = mp;
}
public work(int time) {
hp -= time * 10000;
}
}
// 適当なメソッド
public void foo() {
// ① 人間生成
Human yamada = new Human(65535, 1);
// ② 人間働く(24時間)
yamada.work(24);
// ③ メソッド終了
}
// 人間クラス
class Human {
int hp;
int mp;
public Human(int hp, int mp) {
this.hp = hp;
this.mp = mp;
}
public work(int time) {
hp -= time * 10000;
}
}
// 適当なメソッド
public void foo() {
// ① 人間生成
Human yamada = new Human(65535, 1);
// ② 人間働く(24時間)
yamada.work(24);
// ③ メソッド終了
}
スタックメモリ
変数
yamada
ヒープメモリ
① 人間生成
Humanオブジェクト
Hp : 65535
MP : 1
参照
// 人間クラス
class Human {
int hp;
int mp;
public Human(int hp, int mp) {
this.hp = hp;
this.mp = mp;
}
public work(int time) {
hp -= time * 10000;
}
}
// 適当なメソッド
public void foo() {
// ① 人間生成
Human yamada = new Human(65535, 1);
// ② 人間働く(24時間)
yamada.work(24);
// ③ メソッド終了
}
スタックメモリ
変数
yamada
ヒープメモリ
① 人間生成
Humanオブジェクト
Hp : 65535
MP : 1
参照
スタックメモリ
変数
yamada
ヒープメモリ
② 人間働く(24時間)
Humanオブジェクト
Hp : -174465
MP : 1
参照
// 人間クラス
class Human {
int hp;
int mp;
public Human(int hp, int mp) {
this.hp = hp;
this.mp = mp;
}
public work(int time) {
hp -= time * 10000;
}
}
// 適当なメソッド
public void foo() {
// ① 人間生成
Human yamada = new Human(65535, 1);
// ② 人間働く(24時間)
yamada.work(24);
// ③ メソッド終了
}
スタックメモリ
変数
yamada
ヒープメモリ
① 人間生成
Humanオブジェクト
Hp : 65535
MP : 1
参照
スタックメモリ
変数
yamada
ヒープメモリ
② 人間働く(24時間)
Humanオブジェクト
Hp : -174465
MP : 1
参照
スタックメモリ
変数
yamada
ヒープメモリ
③ メソッド終了
Humanオブジェクト
Hp : -174465
MP : 1
参照
// 人間クラス
class Human {
int hp;
int mp;
public Human(int hp, int mp) {
this.hp = hp;
this.mp = mp;
}
public work(int time) {
hp -= time * 10000;
}
}
// 適当なメソッド
public void foo() {
// ① 人間生成
Human yamada = new Human(65535, 1);
// ② 人間働く(24時間)
yamada.work(24);
// ③ メソッド終了
}
スタックメモリ
変数
yamada
ヒープメモリ
① 人間生成
Humanオブジェクト
Hp : 65535
MP : 1
参照
スタックメモリ
変数
yamada
ヒープメモリ
② 人間働く(24時間)
Humanオブジェクト
Hp : -174465
MP : 1
参照
スタックメモリ
変数
yamada
ヒープメモリ
③ メソッド終了
Humanオブジェクト
Hp : -174465
MP : 1
参照
出番やでー
参照が誰からもされていないので、
おばちゃん(GC)から「ごみ」と認識され、
掃除対象となる
不必要なメモリの基本的な判断方法は、今伝えたものと
なります。では、次に、具体的な手法についてみてみま
しょう!
メモリをお掃除する方法(アルゴリズム)で、最も古く、
そして、基本となる手法は、
「マーク&スイープ GC」
といわれるものになります。
【マークフェーズの概念】
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
【マークフェーズの概念】
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
参照されているオブジェクトをマーク
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
【GCルートについて】
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
この例のように、参照を辿るス
タート地点になるものをGCルート
というよ。
【GCルートについて】
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
この例のように、参照を辿るス
タート地点になるものをGCルート
というよ。
GCルートとなるもの
・スレッドのスタック
・JNI
・ファイナライザキュー
・スタティック変数領域
【スイープフェーズの概念】
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
ヒープメモリ全てをサーチし、マークがついてないオブジェクトを
解放します。あと、ついでに、マークを消してきます。
【スイープフェーズの概念】
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
ヒープメモリ全てをサーチし、マークがついてないオブジェクトを
解放します。あと、ついでに、マークを消してきます。
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトC】
マークアンドスイープGCのメリデリ
【メリット】
実装がシンプルで簡単
参照先を書き換えることがない
【デメリット】
断片化が発生しやすい(フラグメンテーション)
メモリの生成が遅い(アロケーション)
Stop the World の時間が長い
次に、マークアンドスイープ GCの弱点をカバーできる、
「コピー GC」
を紹介します。
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
メモリ空間を2つ分用意し、
そのうち半分のみを利用
From領域
To領域
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
メモリ空間を2つ分用意し、
そのうち半分のみを利用
ルートから辿って、利用されている
オブジェクトをTo領域にコピーします
From領域
To領域
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
From領域
To領域
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトC】
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
メモリ空間を2つ分用意し、
そのうち半分のみを利用
ルートから辿って、利用されている
オブジェクトをTo領域にコピーします
From領域
To領域
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
From領域
To領域
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトC】
コピーする際、参照を
付け替えます。
スタックメモリ
Aへの参照
ヒープメモリ
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトB】 【オブジェクトC】
To領域
From領域
【オブジェクトA】
オブジェクトCへの参照
【オブジェクトC】
FromとTo領域を入れ替えます
コピーGCのメリデリ
【メリット】
Stop the World の時間が短い
メモリの生成が早い(アロケーション)
断片化が発生しない(フレグメンテーション)
【デメリット】
ヒープの使用効率が悪い
参照の書き換えが発生
Javaでは、初期からVer1.4までの間、今紹介した、
「マークアンドスイープGC」と「コピーGC」のメリット
を掛け合わせた「世代別GC」が採用されていました。
マークアンドスイープGC + コピーGC = 世代別GC
・・・というわけで、
長くなってきたので、今回はここまで。
というわけで、長くなってきたので、今回はここまで。
次回は・・・。
Javaで利用された世代別GCとは?
これが、世代別GC・・・
圧倒的じゃないか、我がメモリ管理は
ストップ・ザ・ワールド!!
そして、処理は動き出す・・・
私は念によって、時を止めずに
GCすることに成功した
・・・その名もコンカレントGC
そして、世界はG1GCへと辿りついた・・・
というわけで、長くなってきたので、今回はここまで。
次回は・・・。
Javaで利用された世代別GCとは?
・・・というわけで、
長くなってきたので、今回はここまで。
リクエスト多ければやります・・・。
ご清聴ありがとうございました。

More Related Content

What's hot

サイボウズの CI/CD 事情 〜Jenkins おじさんは CircleCI おじさんにしんかした!〜
サイボウズの CI/CD 事情 〜Jenkins おじさんは CircleCI おじさんにしんかした!〜サイボウズの CI/CD 事情 〜Jenkins おじさんは CircleCI おじさんにしんかした!〜
サイボウズの CI/CD 事情 〜Jenkins おじさんは CircleCI おじさんにしんかした!〜Jumpei Miyata
 
OCIランタイムの筆頭「runc」を俯瞰する
OCIランタイムの筆頭「runc」を俯瞰するOCIランタイムの筆頭「runc」を俯瞰する
OCIランタイムの筆頭「runc」を俯瞰するKohei Tokunaga
 
Kubernetes Meetup Tokyo #35_GitOps Toolkit による Kubernetes マニフェスト CD
Kubernetes Meetup Tokyo #35_GitOps Toolkit による Kubernetes マニフェスト CDKubernetes Meetup Tokyo #35_GitOps Toolkit による Kubernetes マニフェスト CD
Kubernetes Meetup Tokyo #35_GitOps Toolkit による Kubernetes マニフェスト CDPreferred Networks
 
Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6
Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6
Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6Yuji Kubota
 
分散環境におけるDocker とオーケストレーション
分散環境におけるDocker とオーケストレーション分散環境におけるDocker とオーケストレーション
分散環境におけるDocker とオーケストレーションMasahito Zembutsu
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みChihiro Ito
 
今話題のいろいろなコンテナランタイムを比較してみた
今話題のいろいろなコンテナランタイムを比較してみた今話題のいろいろなコンテナランタイムを比較してみた
今話題のいろいろなコンテナランタイムを比較してみたKohei Tokunaga
 
コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話Yuta Shimada
 
GraalVM を普通の Java VM として使う ~クラウドベンチマークなどでの比較~
GraalVM を普通の Java VM として使う ~クラウドベンチマークなどでの比較~GraalVM を普通の Java VM として使う ~クラウドベンチマークなどでの比較~
GraalVM を普通の Java VM として使う ~クラウドベンチマークなどでの比較~Shinji Takao
 
Spanner移行について本気出して考えてみた
Spanner移行について本気出して考えてみたSpanner移行について本気出して考えてみた
Spanner移行について本気出して考えてみたtechgamecollege
 
Concurrent Mark-Sweep Garbage Collection #jjug_ccc
Concurrent Mark-Sweep Garbage Collection #jjug_cccConcurrent Mark-Sweep Garbage Collection #jjug_ccc
Concurrent Mark-Sweep Garbage Collection #jjug_cccYuji Kubota
 
20分でわかるgVisor入門
20分でわかるgVisor入門20分でわかるgVisor入門
20分でわかるgVisor入門Shuji Yamada
 
Spring native について
Spring native についてSpring native について
Spring native についてTakamasa Mitsuji
 
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...NTT DATA Technology & Innovation
 
20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS...
20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS...20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS...
20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS...Amazon Web Services Japan
 
とにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みるとにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みるMasatoshi Tada
 
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -onozaty
 

What's hot (20)

サイボウズの CI/CD 事情 〜Jenkins おじさんは CircleCI おじさんにしんかした!〜
サイボウズの CI/CD 事情 〜Jenkins おじさんは CircleCI おじさんにしんかした!〜サイボウズの CI/CD 事情 〜Jenkins おじさんは CircleCI おじさんにしんかした!〜
サイボウズの CI/CD 事情 〜Jenkins おじさんは CircleCI おじさんにしんかした!〜
 
Mavenの真実とウソ
Mavenの真実とウソMavenの真実とウソ
Mavenの真実とウソ
 
OCIランタイムの筆頭「runc」を俯瞰する
OCIランタイムの筆頭「runc」を俯瞰するOCIランタイムの筆頭「runc」を俯瞰する
OCIランタイムの筆頭「runc」を俯瞰する
 
Kubernetes Meetup Tokyo #35_GitOps Toolkit による Kubernetes マニフェスト CD
Kubernetes Meetup Tokyo #35_GitOps Toolkit による Kubernetes マニフェスト CDKubernetes Meetup Tokyo #35_GitOps Toolkit による Kubernetes マニフェスト CD
Kubernetes Meetup Tokyo #35_GitOps Toolkit による Kubernetes マニフェスト CD
 
Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6
Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6
Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6
 
分散環境におけるDocker とオーケストレーション
分散環境におけるDocker とオーケストレーション分散環境におけるDocker とオーケストレーション
分散環境におけるDocker とオーケストレーション
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
 
今話題のいろいろなコンテナランタイムを比較してみた
今話題のいろいろなコンテナランタイムを比較してみた今話題のいろいろなコンテナランタイムを比較してみた
今話題のいろいろなコンテナランタイムを比較してみた
 
ゼロからはじめるKVM超入門
ゼロからはじめるKVM超入門ゼロからはじめるKVM超入門
ゼロからはじめるKVM超入門
 
コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話コンテナにおけるパフォーマンス調査でハマった話
コンテナにおけるパフォーマンス調査でハマった話
 
GraalVM を普通の Java VM として使う ~クラウドベンチマークなどでの比較~
GraalVM を普通の Java VM として使う ~クラウドベンチマークなどでの比較~GraalVM を普通の Java VM として使う ~クラウドベンチマークなどでの比較~
GraalVM を普通の Java VM として使う ~クラウドベンチマークなどでの比較~
 
Spanner移行について本気出して考えてみた
Spanner移行について本気出して考えてみたSpanner移行について本気出して考えてみた
Spanner移行について本気出して考えてみた
 
Concurrent Mark-Sweep Garbage Collection #jjug_ccc
Concurrent Mark-Sweep Garbage Collection #jjug_cccConcurrent Mark-Sweep Garbage Collection #jjug_ccc
Concurrent Mark-Sweep Garbage Collection #jjug_ccc
 
20分でわかるgVisor入門
20分でわかるgVisor入門20分でわかるgVisor入門
20分でわかるgVisor入門
 
Spring native について
Spring native についてSpring native について
Spring native について
 
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
 
20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS...
20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS...20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS...
20180704 AWS Black Belt Online Seminar Amazon Elastic File System (Amazon EFS...
 
とにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みるとにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みる
 
Metaspace
MetaspaceMetaspace
Metaspace
 
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
 

みんな大好きJava gc入門 【前編】