深入浅出JVM调优,看完你就懂

深入浅出JVM调优,看完你就懂深入浅出JVM调优基本概念:JVM把内存区分为堆区(heap)、栈区(stack)和方法区(method)。由于本文主要讲解JVM调优,因此我们可以简单的理解为,JVM中的堆区中存放的是实际的对象,是需要被GC的。其他的都无需GC。下图文JVM的内存模型从图中我们可以看到,1、JVM实质上分为三大块,年轻代(YoungGen),年老代(OldMemory…

大家好,又见面了,我是你们的朋友全栈君。

 

 

深入浅出JVM调优

基本概念:

JVM把内存区分为堆区(heap)、栈区(stack)和方法区(method)。由于本文主要讲解JVM调优,因此我们可以简单的理解为,JVM中的堆区中存放的是实际的对象,是需要被GC的。其他的都无需GC。

下图文JVM的内存模型

深入浅出JVM调优,看完你就懂

 

从图中我们可以看到,

1、JVM实质上分为三大块,年轻代(YoungGen),年老代(Old Memory),及持久代(Perm,在Java8中被取消,我们不做深入介绍)。

2、垃圾回收GC,分为2种,一是Minor GC,可以可以称为YGC,即年轻代GC,当Eden区,还有一种称为Major GC,又称为FullGC。

3、GC原理:

我们可以看到年轻代包括Eden区(对象刚被new出来的时候,放到该区),S0和S1,是幸存者1区和幸存者2区,从名字可以看出,是当发生YGC,没有被任何其他对象所引用的对象将会从内存中被清除,还被其他对象引用的则放到幸存者区。当发生多次YGC,在S0、S1区多次没有被清楚的对象,则会被移到老年代区域。当老年代区域被占满的时候,则会发送FullGC。

无论是YGC或是FullGC,都会导致stop-the-world,即整个程序停止一些事务的处理,只有GC进程允许以进行垃圾回收,因此如果垃圾回收时间较长,部分web或socket程序,当终端连接的时候会报connetTimeOut或readTimeOut异常,

4、从JVM调优的角度来看,我们应该尽量避免发生YGC或FullGC,或者使得YGC和FullGC的时间足够的短。

JMV调优的准备工作。

1)、配置jstatd的远程RMI服务(当我们要看远程服务器上JAVA程序的GC情况的时候,需要执行此步骤),允许JVM工具查看JVM使用情况。

将如下的代码存为文件 jstatd.all.policy,放到JAVA_HOME/bin中,其内容如下:不知道JAVA_HOME目录的,可以执行 which java查看。

grant codebase “file:${java.home}/../lib/tools.jar” {

permission java.security.AllPermission;

};

执行命令jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=10.27.20.38 &

(10.27.20.38为你服务器的ip地址,&表示用守护线程的方式运行)

2)、执行C:\glassfish4\jdk7\bin\jvisualvm.exe 打开JVM控制台。

工具–插件–中找到Visual GC插件进行安装.

3)、对要执行java程序进行调优,以 c1000k.jar为例,在该jar包所在目录下建立一个start.sh文件,文件内容如下。

java -server -Xms4G -Xmx4G -Xmn2G -XX:SurvivorRatio=1 -XX:+UseConcMarkSweepGC -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1100 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar c1000k.jar&

通过这样的配置,使用JVM控制台即可查看JVM(CPU/内存)及垃圾回收的情况。

4)、控制台配置

打开\jvisualvm.exe,远程—添加远程主机—输入远程IP—-添加JMX连接

深入浅出JVM调优,看完你就懂

 

5)、下面开始正式的JVM调优。

5.1 JVM调优核心为调整年轻代、年老大的内存空间大小及使用GC发生器的类型等。回到上文的start.sh文件内容,我们来分下:

java -server -Xms4G -Xmx4G -Xmn2G -XX:SurvivorRatio=1 -XX:+UseConcMarkSweepGC -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1100 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar c1000k.jar&

这台机器是一个4G内存的机器,因此:

-Xms4G 是指: JVM启动时整个堆(包括年轻代,年老代)的初始化大小。

-Xmx4G 是指: JVM启动时整个堆的最大值。

-Xmn2G是指:年轻代的空间大小,剩下的是年老代的空间。

-XX:SurvivorRatio=1是指:年轻代空间中2个Survivor空间与Eden空间的大小比例。此处为1:1:1,算法如下:比如整个年轻代空间为2G,如果比例为1,那么2/3,则S0/S1/Eden的空间大小是同样的,为666M。

该值不设置,则JDK默认为比例为8,那么是1:1:8,通过上面的算法可以得出S0/S1的大小。我们可以看到官方通过增大Eden区的大小,来减少YGC发生的次数,但有时我们发现,虽然次数减少了,但Eden区满

的时候,由于占用的空间较大,导致释放缓慢,此时stop-the-world的时间较长,因此需要按照程序情况去调优。

-XX:+UseConcMarkSweepGC是指:使用GC的回收类型。这里是CMS类型,JDK1.7以后推荐使用+UseG1GC,被称为G1类型(或Garbage First)的回收器。

5.2当我们设定好start.sh的参数值后,执行./start.sh此时就启动了。

我们可以通过jvisualvm.exe中的Visual GC插件查看GC的图形,我们也可以再服务器上执行:jstat -gc 15016 1000,看到每1秒钟java进程号为15016的GC回收情况。

[root@yxdevapp04 c1000k]# jstat -gc 15016 1000

S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT

699008.0 699008.0 29980.4 0.0 699136.0 116881.6 2097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272

699008.0 699008.0 29980.4 0.0 699136.0 118344.8 2097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272

699008.0 699008.0 29980.4 0.0 699136.0 119895.5 2097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272

699008.0 699008.0 29980.4 0.0 699136.0 121383.1 2097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272

解释如下:

S0C 是指:Survivor0区的分配空间

S0U 是指:Survivor1区的已经使用的空间

EC是指:Eden区所使用的空间

EU是指:Eden区当前使用的空间

OC是指:老年代分配的空间

OU是指:老年代当前使用的空间

PC是指:持久待分配的空间

PU是指:持久待当前使用的空间

YGC是指:年轻代发生的次数,这里是354次

YGCT是指:年轻代发送的总时长,这里是54.272秒,因此每次年轻代发生GC,即平均每次stop-the-world的时长为54.272/354=0.153秒。

FGC是指:年老代回收的次数,或者成为FullGC的次数。

FGCT是指:年老代发生回收的总时长。

GCT是指:包括年轻代YGC及年老代FGC的总时间长。

通常结合图形或数据,我们可以看到当EU即将等于EC的时候,此时发生YGC,因此YGC次数+1,YGCT时间增加。

经过实际的调优测试我们发现,当发生YGC的时候,如果S0U或S1U区如果有任意一个区域为0的时候,此时YGC的速度很快,相反如果S0U或者S1U中都有数据,或相对满的时候,此时YGC的时间边长,这就是因为S0/S1及Eden区的比例问题导致的。

5.3经过一定时间的调优,我们基本上可以使得YGC的次数非常少,时间非常快,很长时间,数天都不会发生FGC,此时JVM的调优算是一个好的结果。

5.4 在MAC电脑上可以通过jconsole调出图形化分析工具。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/138002.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • php stristr_str.center()方法的功能是什么

    php stristr_str.center()方法的功能是什么欢迎进入Linux社区论坛,与200万技术人员互动交流>>进入php中strstr函数的用法:strstr()函数搜索一个字符串在另一个字符串中的第一次出现的字符串。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回false.语法strstr(欢迎进入Linux社区论坛,与200万技术人员互动交流>>进入php中strstr函数的…

    2025年11月12日
    5
  • vboxmanage 常用命令

    vboxmanage 常用命令vBoxManagestartvm”pms(10.0.2.18)”-typeheadlessvBoxManagestartvm”spm(10.0.2.17)”-typeheadless查看有哪些虚拟机VBoxManagelistvms查看虚拟的详细信息VBoxManagelistvms–long查看运行着的虚拟机VBoxManagelistrunningvms开启虚拟机在后台运行VBoxManage…

    2022年5月3日
    44
  • sql索引的建立与使用_sqlserver创建索引语句

    sql索引的建立与使用_sqlserver创建索引语句之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章,自以为就了解了其原理,发现遗漏了些东西,这里自己整理一下这方面的内容。1前言SQL索引有两种,聚集索引和非聚集索引聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续字典的拼音查询法就是聚集索引,字典的部首查询就是一个非聚集索引.聚集索引和非聚集索引的根本区别是表记录的…

    2022年8月30日
    5
  • JSP 标准标签库(JSTL)[通俗易懂]

    JSP 标准标签库(JSTL)[通俗易懂]JSP 标准标签库(JSTL)

    2022年4月22日
    54
  • java虚拟机可以运行的文件_虚拟机的网络模型有

    java虚拟机可以运行的文件_虚拟机的网络模型有Java虚拟机中的内存模型?Java虚拟机运行时内存所有的类的实例(不包括局部变量与方法参数)都存储在Java堆中,每条线程有自己的工作内存(Java栈),不同线程之间无法直接访问对方工作内存中的变量。方法区用于存储被虚拟机加载的类信息、常量、static变量等数据,堆用于存储对象实例,比如通过new创建的对象实例就保存在堆中,堆中的对象的由垃圾回收器负责回收。Java栈用于实现方法调用,每次方法调用就对应栈中的一个栈帧,栈帧包含局部变量表、操作数栈、方法接口等于方法相关的信息,栈中的数据当没有引用指向

    2025年11月25日
    4
  • 数据库中间件简介_数据库中间件还用吗

    数据库中间件简介_数据库中间件还用吗数据库中间件可以简化对读写分离以及分库分表的操作,并隐藏底层实现细节,可以像操作单库单表那样操作多库多表,主流的设计方案主要有两种:1、服务端代理:需要独立部署一个代理服务,该代理服务后面管理多个数据库实例,在应用中通过一个数据源与该代理服务器建立连接,由该代理去操作底层数据库,并返回相应结果。优点是支持多语言,对业务透明,缺点是实现复杂,实现难度大,同时代理需要确保自身高可用2、客户端代理:在连接池或数据库驱动上进行一层封装,内部与不同的数据库建立连接,并对SQL…

    2025年8月5日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号