アラート自身が学び、成長します
1.共通のインタビューの質問
JVMのご理解ご相談ください!新しい仮想マシン何Java8、
JVMは、クロスプラットフォームのJavaの基本である、それはネイティブメソッドライブラリからなる、JVMの時間帯データ、実行エンジン、ローカルライブラリインタフェースを実行します
理由は、生成OOMについて、あなたは話を、OOMとは何ですか?どのように分析するには
OOM:JVMは、オブジェクトのためのスペースを割り当てるための十分なメモリがないので、ガベージコレクタが空間的にリサイクルを持っていないときのOutOfMemoryErrorが、メモリ不足、それはこのエラーをスローします。
原因:
- 仮想マシンのメモリが十分ではありません。
- アプリケーションのメモリフットプリントサーバの現在のサイズは、あなたが大規模な仮想マシンのメモリテストを転送しようとすることができます。
- メモリ/メモリリークのうち、
- パラメータは、プログラムが実行されているときに、メモリのオーバーフローがある場合、ダンプメモリのスナップショットを分析のために生成されて追加することができます。
- 仮想マシンのメモリが十分ではありません。
ここで使用するJVMのチューニングパラメータ
-Xmx:設定された最大ヒープ
-Xms:最小スタックを設定します。
...
メモリのスナップショットを、どのようにクロールに分析し、どのようなコマンド?
使用-XX:+ HeapDumpOnOutOfMemoryErrorコマンドセットが生成されるOOM異常メモリのスナップショット
パーティション内のヒープ:エデン、Survial(へ)から、終身
GCガベージコレクションのアルゴリズムとの?長所と短所について話をします
JVMガベージコレクションのごみ、GCRoots確認する方法
あなたが使用-x -XXパラメータ
JVMのチューニングパラメータは、リリース後にお気に入りのプロジェクト構成となって
参考文献、強い参照、弱参照、ファントム参照はあなたがについて話何ですか
GCおよびGCガベージコレクタアルゴリズムとの関係?何ですか?
G1ガベージコレクタ特性
いくつか見OOM
Javaの-XX:+ PrintCommandLineFlags -version
C:\ Users \ユーザーtianxc>のjava -XX:+ PrintCommandLineFlags -version
-XX:InitialHeapSize = 266536512 -XX:MaxHeapSize = 4264584192 -XX:+ PrintCommandLineFlags -XX:+ UseCompressedClassPointers -XX:+ UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX: + UseParallelGC
Javaのバージョン"1.8.0_191"
のJava(TM)SEランタイム環境(ビルド1.8.0_191-B12)
は、Java HotSpot(TM)64ビットサーバーVM(ビルド25.191-B12、混合モード)
2.JVM場所
3.JVMアーキテクチャ
私たちは、いわゆるチューニングはチューニングであるヒープ
4.クラスローダ
クラスをロードすると、接続と初期化
ロード:バイナリデータのクラスを見つけ、ロード
接続:
- 確認してください:ロードされたクラスの正確さを保証
- 準備:静的変数は、クラスのメモリ領域を割り当てるデフォルトの初期値を代入します
- 分析:クラスが直接参照シンボル参照に変換され、
シンボリック参照:Javaクラスファイルにコンパイルすると、仮想マシンは、ニーモニックが参照するアドレスを知りません!本当、直接アドレスへの直接参照に対応する見つけること。
初期化:正しい値のクラスに割り当てられた静的変数。
public class Test{
public static int a=1;
}
//1.加载 编译文件为.class文件,通过类加载,加载到JVM
//2.连接
//验证(1) 保证class类文件没有问题
//准备(2) 给int类型分配内存空间,a=0;
//解析(3) 符号引用转换为直接引用。
//3.初始化
//经过这个阶段的解析,把1赋值给变量a
ロード静的クラス
package com.ruyidd.classloader;
/**
* @author: tianxc
* @date: 2020-03-10 15:13
* @desc: JVM参数:-XX:+PrintGCDetails//打印GC垃圾回收信息
* -XX:+TraceClassLoading 打印类加载信息
* rt.jar jdk出厂自带的,最高级别的类加载器要加载的。
*/
public class Demo01 {
public static void main(String[] args) {
System.out.println(MyChild01.str2);
}
}
class Myparent01{
private static String str = "hello,world";
static {
System.out.println("Myparent01 static");
}
}
class MyChild01 extends Myparent01{
public static String str2 = "hello,str2";
static {
System.out.println("MyChild1 static");
}
}
コンパイル時に、最終的な定数彼は一定のプールに入れます:
これは、定数プールDemo02のコード定数を置く、Demo02とMyParent02た後、それは問題ではありません。
package com.ruyidd.classloader;
/**
* @author: tianxc
* @date: 2020-03-10 16:55
* @desc:
*/
public class Demo02 {
public static void main(String[] args) {
//直接从常量池中获取
System.out.println(MyParent02.str);
}
}
class MyParent02{
public static final String str = "hello world";
//
static {
System.out.println("MyParent02 static");
}
}
package com.ruyidd.classloader;
import java.util.UUID;
/**
* @desc: 当一个常量的值并非编译的期间可以确定的,
* 那这个值就不会被放入方法调用类的常量池中
* 程序运行期间的时候,会主动使用常量所在的类
*/
public class Demo03 {
public static void main(String[] args) {
System.out.println(MyParent03.str);
}
}
class MyParent03{
public static final String str = UUID.randomUUID().toString();
static {
System.out.println("MyParent03 static");
}
}
クラスローダの分類
- ローダーが付属してJava仮想マシン
- (ローディングシステムのコアライブラリrt.jar内JDKクラス)ブートストラップルートローダ
- 内線延長クラスローダ(拡張負荷いくつかのjarパッケージクラス)
- SYS /アプリケーションシステム(アプリケーションクラス)ローダー(当社独自のクラスを記述)
- ユーザー定義ローダー
- クラスローダは、唯一、独自のクラスローダを定義することができ、この抽象クラスを拡張する必要があります
package com.ruyidd.classloader;
/**
* @author: tianxc
* @date: 2020-03-10 17:17
* @desc:
*/
public class Demo04 {
public static void main(String[] args) {
Object o = new Object();
Demo04 demo04 = new Demo04();
//null 在这里并不代表没有,只是Java触及不到
System.out.println(o.getClass().getClassLoader());//null
System.out.println(demo04.getClass().getClassLoader());//sun.misc.Launcher$AppClassLoader@18b4aac2
System.out.println(demo04.getClass().getClassLoader().getParent());//sun.misc.Launcher$ExtClassLoader@1b6d3586
System.out.println(demo04.getClass().getClassLoader().getParent().getParent());//null
}
}
:親はメカニズム任命ローダーのトップがダウンにそう、負荷、およびすることができない場合は、負荷に1レベルとなるよう親クラスを。
両親は、クラスの独自の定義によって置き換えられませんコアJavaクラスを保護するためのメカニズムを委任します
5.native:ローカル方法
ネイティブ:長いこれがキーワードである限り、基本的なC言語のライブラリを呼び出すためだけでなく、Javaの範囲を示します
ロボットクラス
JNI:Javaネイティブ整数(Javaのネイティブメソッドインタフェース)
6.プログラムカウンタ
各スレッドは、プログラムカウンタを持って、プライベートスレッド。
プログラムカウンタ)は、非常に小さなメモリ空間:(ほとんど無視できます
処置:現在の行番号インジケータバイトコード実行。
bipush
整数、浮動小数点、文字列、スタックの一定値にプッシュ。
istore
ローカル変数テーブルにオペランドスタックから値を格納します
iadd
プラス
imul
乗算
7.メソッド領域
方法エリア方式エリアは、スレッド間で共有することができるように、ランタイムデータ領域Java仮想マシン仕様は、定義された、およびヒープ(ヒープ)の一つであります
JDK1.7前
永久世代:ロード・クラス情報、定数、文字列や静的変数への仮想マシンの一部を格納するために使用されます。これらのことは、恒久的な世代を置く;永久世代空間のサイズが制限されています:完全な場合のOutOfMemoryError:PermGen
JDK1.8
(HotSpotのJVM jdk1.8時)世代完全に除去、Javaヒープまたはメタスペース(ネイティブヒープ)の要素スペースを永久う
人民元は、HotSpotのJVMで空き領域を達成するための方法です
この方法は、領域を節約するために主にある:クラス情報、定数、文字列、静的変数、符号、メソッドコード
世代永久次元空間は、JVM帯指定方法を達成しています。
人民元と代わっ最大の違いに永久スペース:次元空間は、ローカルメモリを使用して、Java仮想マシンではありません。
-XX:MetaspaceSize10m
元スペースがいっぱいになっている場合:OutOfMemoryErrorが発生:メタスペース
8.スタック(スタック)
スタックとキュー(スタックやキューは、基本的なデータ構造です。)
スタックとキューは、基本的なデータ構造であります:
このプログラムは、実際のプロセスをプッシュされて実行されています。
スタックが空である、スレッドは終わりました。
スタックスタックとは何ですか
ランタイム・スタックは、管理プログラムであります
基準値のいくつかの基本的なタイプは、オブジェクト、メソッドなどを保管していました。。。
スタックの利点:速い反応装置よりもアクセス速度は、レジスタの後、スタックデータを共有することはできません。
StackOverflowErrorがスタックオーバーフロー
public class Demo01 {
public static void main(String[] args) {
a();
}
//Exception in thread "main" java.lang.StackOverflowError
private static void a(){
a();
}
}
完成したら、スレッド限り、確かにガベージコレクションの問題ではありませんスタックは、スタックは、ライフサイクルとスレッドの一貫性、以上です。
スタックの原則
Javaスタックの構成要素:スタックフレーム
スタック(どのような預金?)+ +ヒープ相互作用図のメソッドエリア
スタックデポジット:ローカル変数テーブル、データの基本型(int型、ダブル...)、オブジェクト参照、インデックス付けの方法...
これが私たちのメインスタックのHotSpot(ポインタ)であります
3 JVM:
- SUNのHotSpot
- BEA JRockitのさん
- IBMのJ9VM
9.ヒープ(ヒープ)
Java7の前に:
ヒープスタック、ヒープJVM単なる一例では、メモリのサイズは調整可能です。
あなたは、コンテンツを保存することができます:クラス、メソッド、定数は、参照情報の真のタイプを保持しています。
3つの部分に分かれ:
- 新生児領域:ヤング(エデン-S0-S1)
- 年金地区:旧テニュア
- 常設エリア:ペルミ
新生児、年金、永久(以下、素子間隔JDK1.8):ヒープメモリは、論理的に3つの部分に分かれ
物理的にのみ、生まれたばかりの年金、ローカルメモリ空間ではなく、JVMの要素。
主に若い世代や年金エリアでのGCのガベージコレクションは、通常のGCに分割され、完全なGCは、満たされた場合、OutOfMemoryErrorが破裂します
若い世代
若い世代が出産のクラス、場所の成長終焉であります
若い世代セグメント:エデン、ときフルS0、S1(へ、から)、すべてのクラスがゆっくりと新しいエデン、エデンに出てきた、プログラムは、オブジェクトを作成する必要があり、彼らは軽量をトリガーしますGC;ゴミオブジェクトが生き残るの後、我々は(S0、S1)の生存者ゾーンを置く清掃、クリーンアップ15回後、いくつかの非常に粘り強いオブジェクトが存在している、いくつかのオブジェクトがガベージを通じて15回を破りますその後、この時間は、数ヶ月のために実行されている、年金エリアに対象となります年金面積がいっぱいになる、それはフルGCがトリガされます。全体のスペースが完全にいっぱいする場合は、OOMに。
太陽のHotSpot仮想マシン、メモリ管理(世代管理機構は、異なる領域は、異なるアルゴリズムを使用します。)
へのエデン
年金エリア
年金領域がいっぱいになった後、15個のオブジェクトは、年金エリアにトリガーのフルGCを生き残りました
デフォルトは、15回に変更することができています
永久的な領域(パーマ)
JDKには、いくつかは、自分のクラスを運ぶメタデータの整数を置きます
ほとんどのガベージコレクション:
OutOfMemoryErrorが発生:PermGenをプロジェクトが十分ではない恒久的な代理を起動したとき:サードパーティの多数のパッケージをロードすることが可能です。
定数プールエリア内の永続的な生成方法:JDK1.6前
jdk1.7:永久に代わったが、彼はヒープに、永久世代に一定のプールを試みるようになりました
jdk1.8:パーマネント、置換員空間のNO発生、素子空間における定数プール。
方法およびヒープ領域は、共有領域であり、JVM仕様の論理的な部分である、としても彼に呼ばれる非ヒープ
次元空間:ローカルメモリ
10.ヒープメモリチューニング(初期)
テストを調整します。
package com.ruyidd.heap;
/**
* 默认情况
* maxMemory=3791650816(字节) 3616.0MB(虚拟机试图使用的最大的内存 一般是物理内存的1/4)
* totalMemory=257425408(字节) 245.5MB(虚拟机默认初始内存总量 一般是物理内存的1/64)
*
* 我们可以自定义堆内存的总量:
* -XX:+PrintGCDetails;//输出详细的垃圾回收信息
* -Xmx:最大分配内存 1/4
* -Xms:初始分配的内存大小1/64
* -Xmx1024m -Xms1024m -XX:+PrintGCDetails
*/
public class Demo01 {
public static void main(String[] args) {
//获取堆内存的初始大小和最大大小
long maxMemory = Runtime.getRuntime().maxMemory();
long totalMemory = Runtime.getRuntime().totalMemory();
System.out.println("maxMemory="+maxMemory+"(字节)\t"+(maxMemory/1024/(double)1024)+"MB");
System.out.println("totalMemory="+totalMemory+"(字节)\t"+(totalMemory/1024/(double)1024)+"MB");
}
}
テスト2:OOM
package com.ruyidd.heap;
import java.util.Random;
/**
* -Xmx8m -Xms8m -XX:+PrintGCDetails
*
* [GC (Allocation Failure) [PSYoungGen: 1536K->488K(2048K)] 1536K->640K(7680K), 0.0009800 secs] [Times: user=0.05 sys=0.00, real=0.00 secs]
* [Full GC (Ergonomics) [PSYoungGen: 1981K->0K(2048K)] [ParOldGen: 4775K->2733K(5632K)] 6757K->2733K(7680K), [Metaspace: 3204K->3204K(1056768K)], 0.0039491 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
* 1. GC类型:GC——普通GC;Full GC——重GC
* 2. 1536K 执行GC之前的大小
* 3. 488K 执行GC之后的大小
* 4. (7680K) young 的total大小
* 5. 0.0009800 secs清理的时间
* 6. user 总计GC所占用CPU的时间 sys os调用等待的时间 real 应用暂停的时间
*
* GC的执行方式:串行执行STW(stop The World);并行执行:G1
*/
public class Demo02 {
public static void main(String[] args) {
String str = "lkasjdflkajlfkjakdjfalkdsfj";
while (true){
str += str
+ new Random().nextInt(999999999)
+ new Random().nextInt(999999999);
}
//出现的问题 java.lang.OutOfMemoryError: Java heap space
}
}
11.Dumpメモリのスナップショット
ビューツール:
- jconsoleを
- エクリプス(MAT)
- アイデア(Jprofileプラグイン)
Jprofileプラグ
高速経験