JVMチューニングとメモリ割当方式(ベースJDK1.8)

1.はじめに

最も一般的なJavaプログラミング言語の一つとして、Javaは基礎となるJVM Javaプログラミング言語のコアがあります。エンタープライズアプリケーション内かどうかは、モバイルデータ端末や大面積は、大きな市場シェアを持っています。Javaはまた、ガベージコレクションのメカニズムのように、いくつかの欠陥を、より多くの人気の急速な発展により平坦化しますが、C / C ++と比較して、Java言語。ガベージコレクションは何ですか、それはJavaやC / C ++関係のためであるかどうか、単純に出てきた、すべてがオブジェクト、オブジェクトが作成されたとき、私たちはチームやスタックのフットプリントを割り当てる必要がありますです。オブジェクトがインスタンス化されると、それが引用されていませんでした。ここでは、すぐに参照された後、回復していない場合、オブジェクトは、引用されることはありませんことを確認し、問題があるでしょう。JavaとC / C ++でこれは、二つの異なるスキームです。オブジェクトが参照され、その後、資源のリサイクルオブジェクトを解放していない独自のスクリーニングに必要なC / C ++の開発者。しかし、Javaで、自動的にファイナライズオブジェクトによって、C / C ++の機能を維持するものの、Javaの()メソッドガベージコレクションされているが、それは、Java開発者は、この作業はガベージコレクションJVMになることをお勧めします。だから、本当にパフォーマンスのJavaプログラムやアプリケーション開発システムを改善したい、我々はJVMの深い理解を持っている必要があり、これは、最適化プログラムになります。Jdk1.8この記事は、JVMのいくつかの共通のコアと最適化を導入します。

2.JVMレイアウト

メモリは、リアルタイムオペレーティングシステムとアプリケーションを運んで、非常に重要なシステムリソース、CPUやハードディスクストレージと中間ブリッジです。JVMのメモリレイアウトは、JVMの効率的かつ安定した動作を確保するための操作、配布および管理戦略の間Javaアプリケーションメモリを提供します。

2.1。を押してメモリレイアウト

2.2。レイアウトはスレッドによって共有されています

2.3。ヒープ(ヒープ)

私は、ヒープ、(赤でマーク)は、例えば2.1にメモリレイアウト、あなたはJVMとJava開発者について何かを行っている場合は、ヒープメモリ領域を知っている理由についてお話しましょう、すべてのスレッドで共有されている領域の最大の作品です、ほとんどの店ほとんどすべてのオブジェクトのインスタンスの、オブジェクトのほぼすべてのインスタンスはヒープ上に割り当てられている(なぜここではなく、使用よりもほぼ確実、エスケープJITコンパイラの解析技術の成熟する、スタック上の分布、スカラー交換用の最適化技術の開発であるためいくつかの微妙な変化をもたらすだろう、すべてのオブジェクトが徐々に少なく、「絶対に」なり、ヒープ上に割り当てられています)。それはほとんどすべてのオブジェクトが作成された場所であるので、その後、ヒープは、ガベージコレクタによって管理される主な自然地域で、また、GCヒープとして知られています。

デフォルトの割り当てA。ヒープ

B。あなたは、割り当てられたコマンドの割合を表示することができます
$:java -XX:+PrintFlagsFinal –version

百このコマンドは、意志の出力数行は、ここでは、関連する2つのパラメータとヒープメモリの割り当てを参照してください

uintx   InitialSurvivorRatio=8
uintx   NewRatio=2

パラメータ詳細:
InitialSurvivorRatio初期のエデン/ Survicorスペース比の新世代
NewRatioメモリ面積比古/ヤング・エリア

新しい世代がされているのでEden + S0 + S1なるメモリサイズは、次いで、2つの領域を領域40Mをエデンされている場合、そう、上記デフォルトのスケーリングに生き残り5Mさよれば、若い全領域が50M、メモリ領域サイズを算出する旧100M、ヒープチーフのサイズであります150Mです。

調整C。ヒープ領域

Java仮想マシンの仕様では、Javaのヒープは、私たちのディスクスペースのような、に限り、論理的に連続、不連続な物理メモリ空間であってもよいです。実装された場合、それは固定されたサイズは、実行時に動的に調整することができるいずれかとして実装されてもよいです。
例えば、初期値とヒープの最大値に設定することができ、以下のパラメータを設定することにより、-Xms256M-Xmx1024M文字が-XそれJVMランタイムパラメータを表し、MSは、メモリスタート、初期値メモリ中国の手段と呼ばれ、MXは、メモリmaxはあります短い、最大メモリことを意味します。

2.4メタデータ領域

メタスペース恒久的性質と類似するが、メソッド領域JVM仕様で達成されます。しかし、それに代わって元と永久スペースの最大の違いに:元は、仮想マシン内のスペースはありませんが、ローカルメモリを使用します。したがって、デフォルトでは、要素の空間の大きさは、ローカルメモリの制限によって。
Javaプログラムのフローチャートおよび2.1はじめに2.2ヒープからは、ヒープ内のほぼすべてのオブジェクトを知ることができます。メタデータ地区、一定のプールについては、ストレージスペースの方法メタ情報領域には、リソースおよびメタ情報クラスを占めていました。この種の情報については、Javaプログラムでは、リソース情報の量は、占有がヒープメタデータより少ないプログラムのパフォーマンスへの影響に対して固定されて起動します。
メタデータ領域のパラメータの最適化:

3.オブジェクトのライフサイクル

上記の説明から、我々は、Javaオブジェクトする位置を知ることができますが、十分ではない、だけは本当に最適化を行うためにオブジェクトとメモリ割り当てプロセスのライフサイクルを理解しています。

ローディングエリアがエデン満たされたときエデンエリア内のオブジェクトのほとんどは、トリガを生成YoungGarbageCollectionYGCこと。ガベージコレクション時間は、エデンの領域に明確な戦略を達成するため、オブジェクトを直接回復を参照されていません。まだ生きているオブジェクトは、サバイバーの領域に転送されます。サバイバーs1とので、2つのメモリ空間に分割されます。YGCたびに、彼らはその後のスペースは現在、2つの交換スペースの状態を使用して、完全に除去使用され、未使用領域の一部にコピーされたオブジェクトを生きるのです。YGCを転送するオブジェクトの上限は、サバイバー地区の容量よりも大きい場合は、直接、古い時代に引き渡さ。オブジェクト18年に男性がJVMの中で、大人のようになりますように、常に、新しい世代にとどまることができない-XX:MaxTenuringThresholdオブジェクトを設定するためのパラメータは、古い時代のしきい値に新世代から促進されます。デフォルト値は15で、地域における為替サバイバー14回の後に、古い時代に昇進しました。

4. jvisualvmJVM GCモニタリングの

4.1。インストールVisual GCのプラグインを

在jdk的bin目录下有一个jvisualvm.exe,这个程序是jvm自带的对jvm的全方位监控,但需要安装对应的插件。这里只介绍对GC的监控。
运行jvisualvm.exe

工具->插件->设置

这里更改插件中心的代理,一般配置为一下代码:
https://visualvm.github.io/archive/uc/8u40/updates.xml.gz
但需要对应你的jdk版本

配置好后再插件中选择可用插件,勾选Visual GC点击安装

4.2.利用jvisualvm对java程序进行JVM GC监控

a.程序
package com.surfilter;

import java.util.LinkedList;
import java.util.List;

public class ChDDLDemo {
    public static void main(String args[]) throws Exception{
        System.out.println("HelloGC!");
        List list = new LinkedList();
        for(;;) {
            byte[] b = new byte[1024*1024];
            Thread.sleep(500);
            list.add(b);
        }
    }
}

该程序的逻辑十分简单,再一个死循环中不断的new新的对象,这个程序最终是会出现异常的。

b.启动程序运用Visual GC监控

当程序启动后可以看到本地有这个程序的类(当然也可以进行远程的java程序的监控),双击这个类,可以看到该程序的一些信息,点击Visual GC,会出现以下信息

监控是实时的,可以看到Metaspace是保持不变的,Old区,Eden区,S0,S1区都是在实时更新的,同时在右侧依次往下可以看到编译的时间,GC的回收的时序关系,S0区的内存时序关系,S1区的内存时序关系,Old区的时序关系以及Metaspace的时序关系。从监控图的实时状态中可以看出与对象的周期架构完全符合,等待该程序出异常,来查看这个监控在出现异常和正常执行之间的区别

现在来看Visual GC的监控图

可以看出Old在上升直到满了导致程序异常,而且整个过程都在频繁的进行GC。如果在生产环境的程序GC出现如上图的情况,肯定性能会打折扣,深圳导致生产环境程序崩溃。如果要避免这些问题,第一要素是使堆在每个区都有空间,第二要素是使程序不会过多的进行GC。这就是JVM优化调优的核心。针对于第二点要从代码规范层面上着手,避免过多的不用对象。第二点则是针对于JVM的参数调优,在实际的开发中,两种情况都会有,但第一种可能更为常见,接下来具体将针对的JVM的参数调优。

5.JVM调优

调优更多的实际应用中进行的,正如某位大神说的,没有业务场景的调优都是耍流氓。这里只是提供一些调优的方案。
如上2.3的c对堆区的大小调整和对元数据的资源占用的调整,还有很多的调优方案

5.1.调优的步骤

a.熟悉业务场景(没有最好的垃圾回收器,只有最合适的垃圾回收器)
b.了解程序的响应时间、停顿时间
c.调研吞吐量 = 用户时间 / 用户时间 + GC时间
d.选择回收器组合
e.计算内存需求
f.设定年代大小、升级年龄
g.设定日志参数

-Xloggc:/opt/xxx/logs/xxx-xxx-gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCCause
观察日志情况

5.2.两个核心的JVM优化方案

a.尽量减少YoungGC,以减少代码停顿
b.尽量减少FullGC,以减少系统停顿

在4.2中监控可以看出GC的次数非常多,GC分为YoungGC和FullGC,可见YoungGC和FullGC是非常多的,一天最多 FullGC 一次,最好在系统空闲期(如深夜)

5.3.参数级调优

选项 -Xms300M -Xmx300M -XX:NewRatio=2 -XX:SurvivorRatio=8 -XX:PermSize=100M -XX:MaxPermSize=100M 含义为:

  • 永久代固定尺寸为 100M;
  • 整个堆固定尺寸为 300M,其中“老年代 / 新生代”为-XX:NewRatio=2,所以老年代为 200M,新生代为 100M;
  • 新生代总共 100M,其中“Eden / Survivor0”为-XX:SurvivorRatio=8,所以 Eden 为 80M,Survivor0=Survivor1=10M。
    可以对以上参数适当的加大
    官方资料:http://www.oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html
    实际的参数级调优方案很多,可以参照oracle官网

おすすめ

転載: www.cnblogs.com/jiashengmei/p/12217949.html