1.jvm的运行参数

在jvm中有很多的参数可以进行设置,这样可以让jvm在各种环境中都能够高效的运行。绝大部分的参数保持默认即可。

1.1 三种参数类型

jvm的参数类型分为三类,分别是 :
标准参数 :
-help
-version
-X参数(非标准参数)
-Xint
-Xcomp
-XX参数(使用率较高)
-XX:newSize
-XX:+UseSerialGC

1.1.1 -server与-clinet参数

可以通过-server或-client设置jvm的运行参数。
(1)它们的区别是Server VM的初始堆空间会大一些,默认使用的是并行垃圾回收器,启动慢运行快。
(2)Client VM相对来讲会保守一些,初始堆空间会小一些,使用串行的垃圾回收器,它的目标是为了让JVM的启动速度更快,但运行速度会比Server VM模式慢些。
(3)JVM在启动的时候会根据硬件和操作系统自动选择使用Server还是Client类型的JVM。
(4)32位操作系统
1)如果是Windows系统,不论硬件配置如何,都默认使用Client类型的JVM。
2)如果是其他操作系统上,机器配置有2GB以上的内存同时有2个以上CPU的话默认使用server模式,否则使用client模式。
(5)64位操作系统
1)只有server类型,不支持client类型。

2.1 -X参数

jvm的-X参数是非标准参数,在不同版本的jvm中,参数可能会有所不同,可以通过java -X查看非标准参数。
-Xmixed:混合模式执行(默认)
-Xint:仅解释模式执行
-Xbootclasspath:(用;分隔的目录和zip/jar文件)设置搜索路径以引导类和资源
-Xbootcalsspath/a:(用;分隔的目录和zip/jar文件) 附加在引导类路径末尾
-Xbootcalsspath/p:(用;分隔的目录和zip/jar文件)置于引导类路径之前
-Xdiag :显示附加诊断消息
-Xnoclassgc :禁用类垃圾收集
-Xincgc : 启用增量垃圾收集
-Xloggc:<file> : 将GC状态记录在文件中(带时间戳)
-Xbatch :禁用后台编译
-Xms<size> : 设置初始java堆大小
-Xmx<size> : 设置最大java堆大小
-Xss<size> : 设置java线程堆栈大小
-Xprof : 输出cpu配置文件数据
-Xfuture : 启用最严格的检查,预期将来的默认值
-Xrs : 减少java/VM 对操作系统信号的使用(请参阅文档)
-Xcheck:jni : 对JNI函数执行其他检查
-Xshare:off : 不尝试使用共享类数据
-Xshare:auto : 在可能的情况下使用共享类数据(默认)
-Xshare:on : 要求使用共享类数据,否则将失败
-XshowSettings:all : 显示所有设置并继续
-XshowSettings:vm : 显示所有与vm相关的设置并继续
-XshowSettings:properties : 显示所有属性设置并继续
-XshowSetting:locale : 显示所有与区域设置相关的设置并继续

2.1.1 -Xint、-Xcomp、-Xmixed

在解释模式(interpreted mode)下,-Xint标记会强制JVM执行所有的字节码,当然这会降低运行速度,通常低10倍或更多。
(编译比较快,运行比较慢)
-Xcomp参数与它(-Xint)正好相反,JVM在第一次使用时会把所有的字节码编译成本地代码,从而带来最大程度的优化。
然而,很多应用在使用-Xcomp也会有一些性能损失,当然这比使用-Xint损失的少,原因是-Xcomp没有让JVM启用JIT编译器的全部功能。
JIT编译器可以对是否需要编译做判断,如果所有代码都进行编译的话,对于一些只执行一次的代码就没有意义了。
(
-Xmixed是混合模式,将解释模式与编译模式进行混合使用,由jvm自己决定,这是jvm默认的模式,也是推荐使用的模式。

3.1 -XX参数

-xx参数也是非标准参数,主要用于jvm的调优和debug操作。
-xx参数的使用有2种方式,一种是boolean类型,一种是非boolean类型:
boolean类型
格式 :-xx:[+-]<name> 表示启用或禁用<name>属性
如 :-xx:+DisableExplicitGC 表示禁用手动调用gc操作,也就是说调用System.gc()无效
非boolean类型
格式 :-xx:<name>=<value> 表示<name>属性的值为<value>
如 :-xx:NewRatio=1 表示新生代和老年代的比值

4.1 -Xms与-Xmx参数

-Xms与-Xmx分别是设置jvm的堆内存的初始大小和最大大小。
-Xmx2048m : 等价于-XX:MaxHeapSize,设置JVM最大堆内存为2048M。
-Xms512m :等价于-XX:InitialHeapSize,设置JVM初始堆内存为512M。
适当的调整jvm的内存大小,可以充分利用服务器资源,让程序跑的更快。

5.1 查看jvm的运行参数

有时候我们需要查看jvm的运行参数,这个需求可能会存在2中情况:
第一,运行java命令时打印出运行参数;
第二,查看正在运行的java进程的参数;

5.1.1 运行java命令时打印参数

运行java命令时打印参数,需要添加-XX:+PrintFlagsFinal参数即可。	其中参数有boolean类型和数字类型,值的操作符是=或:=,分别
代表默认值和被修改的值。
查看所有的参数,用法 :jinfo -flags <进程id>
通过jps 或者 jps -l 查看java进程
查看某一参数的值,用法 :jinfo -flag <参数名> <进程id>

6.1 jdk1.7的堆内存模型

Young年轻区(代)
Young区被划分为三部分,Eden区和两个大小严格相同的Survivor区,其中,Survivor区间中,某一时刻只有其中一个是被
使用的,另外一个留做垃圾收集时复制对象用,在Eden区间变满的时候,GC就会将存活的对象移到空闲的Survivor区间中
,根据JVM的策略,在经过几次垃圾收集后,任然存活于Survivor的对象将被移动到Tenured区间。
Tenured年老区
Tenured区主要保存生命周期长的对象,一般是一些老的对象,当一些对象在Young复制转移一定的次数以后, 对象就会被
转移到Tenured区,一般如果系统中用了application级别的缓存,缓存中的对象往往会被转移到这一区间。
Perm 永久区
Perm代主要保存class,method,filed对象,这部分的空间一般不会溢出,除非一次性加载了很多的类,不过在涉及到热部
署的应用服务器的时候,有时候会遇到java.lang.OutOfMemoryError : PermGen space的错误,造成这个错误的很大原因就
有可能是每次都重新部署,但是重新部署后,类的class没有被卸载掉,这样就造成了大量的class对象保存在了perm中,这
种情况下,一般重新启动应用服务器可以解决问题。
Virtual区
最大内存和初始内存的差值,就是Virtual区。

6.2 jdk1.8的堆内存模型


由上图可以看出,jdk1.8的内存模型是由2部分组成,年轻代 + 年老代。
年轻代 :Eden + 2 * Survivor
年老代 :OldGen
在jdk1.8中变化最大的Perm区,用Metaspace(元数据空间)进行了替换。
需要特别说明的是 :Metaspace所占用的内存空间不是在虚拟机内部,而是在本地内存空间中,这也是与1.7的永久代最大的
区别所在。

6.3 为什么要废弃1.7中的永久区?

移除永久代是为融合HotSpot JVM与JRockit VM而做出的努力,因为JRockit没有永久代,不需要配置永久代。
现实使用中,由于永久代内存经常不够用或发生内存泄漏,爆出异常java.lang.OutOfMemoryError : PermGen.
基于此,将永久区废弃,而改元空间,改为了使用本地内存空间。

6.4 通过jstat命令进行查看堆内存使用情况

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下 :
jstat[-命令选项][vmid][间隔时间/毫秒][查询次数]
6.4.1 查看class加载统计


说明 :
Loaded : 加载class的数量
Bytes : 所占用空间大小
Unloaded : 未加载数量
Bytes : 未加载占用空间
Time : 时间

6.4.2 查看编译统计

jstat -compiler 

说明 :
Compiled : 编译数量
Failed : 失败数量
Invalid : 不可用数量
Time : 时间
FailedType : 失败类型
FailedMethod : 失败的方法

6.4.3 垃圾回收统计

jstat -gc 

也可以指定打印的间隔和次数,每1秒中打印一次,共打印5次
jstat -gc 1000 5

说明 :
S0C : 第一个Survivor区的大小(KB)
S1C : 第二个Survivor区的大小(KB)
S0U : 第一个Survivor区的使用大小(KB)
S1U : 第二个Survivor区的使用大小(KB)
EC : Eden区的大小(KB)
EU : Eden区的使用大小(KB)
OC : Old区大小(KB)
OU : Old使用大小(KB)
MC :方法区大小(KB)
MU :方法区使用大小(KB)
CCSC :压缩类空间使用大小(KB)
CCSU :压缩类空间使用大小(KB)
YGC :年轻代垃圾回收次数
YGCT :年轻代垃圾回收消耗时间
FGC :老年代垃圾回收次数
FGCT : 老年代垃圾回收消耗时间
GCT :垃圾回收消耗总时间

7.1 查询内存使用情况

前面通过jstat可以对jvm堆的内存进行统计分析,而jmap可以获取到更加详细的内容,如 :内存使用情况的汇总、对内存溢出的定位与分析。
查看内存使用情况 :
jmap -heap <vmid>



7.2 查看内存中对象数量及大小

查看所有对象,包括活跃以及非活跃的
jmap -histo <pid> | more
查看活跃对象
jmap -histo:live <pid> | more


对象说明 :
B : byte
C : char
D : double
F : float
I : int
J : long
Z : boolean
[ : 数组,如[I表示int[]
[L+类名 :其他对象

7.3 将内存使用情况dump到文件中

有些时候我们需要将jvm当前内存中的情况dump到文件中,然后对它进行分析,jmap也是支持dump到文件中的。
用法 :
jmap -dump:format=b,file=dumpFileName <pid>
其中b是代表二进制
示例 :
jmap -dump:format=b,file=/tmp/dump.dat 6219

7.4 通过jhat对dump文件进行分析

用法 :
jhat -port <port> <file>
例如 :
jhat -port 9999 /test/dump.dat
这个时候就可以打开浏览器访问 :127.0.0.2:9999
-Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError : 设置初始堆大小和当发生内存溢出时,给内存一个快照并导出一个dump文件
用MAT进行文件分析

8 jstack的使用

有些时候我们需要查看下jvm中的线程执行情况,比如,发现服务器的CPU的负载突然增高了、出现了死锁、死循环等,我们
如何分析呢?
由于程序是正常运行的,没有任何的输出,从日志方面也看不出什么问题,所以就需要看下jvm的内部线程的执行情况,然后
再进行分析查找出原因。
这个时候,就需要借助于jstack命令了,jstack的作用是将正在运行的jvm的线程情况进行快照,并且打印出来 :
用法 :jstack <pid>

8.1 线程的状态

在java中线程的状态一共被分成6种 :
初始态(NEW)
创建一个Thread对象,但还未调用start()启动线程时,线程处于初始态。
运行态(RUNNABLE),在java中,运行态包括就绪态和运行态。
就绪态
该状态下的线程已经获得执行所需的所有资源,只要CPU分配执行权就能运行。
所有就绪态的线程存放在就绪队列中。
运行态
获得CPU执行权,正在执行的线程。
由于一个CPU同一时刻只能执行一条线程,因此每个CPU每个时刻只有一条运行态的线程。
阻塞态(BLOCKED)
当一条正在执行的线程请求某一资源失败时,就会进入阻塞态。
而在java中,阻塞态专指请求锁失败时进入的状态。
由一个阻塞队列存放所有阻塞态的线程。
处于阻塞态的线程会不断请求资源,一旦请求成功,就会进入就绪队列,等待执行。
等待态(WAITING)
当前线程中调用wait、join、park函数时,当前线程就会进入等待态。
也有一个等待队列存放所有等待态的线程。
线程处于等待态表示它需要等待其他线程的指示才能继续运行。
进入等待态的线程会释放CPU执行权,并释放资源(如 :锁)。
超时等待态(TIMED_WAITING)
当运行中的线程调用sleep(time)、wait、join、parkNanos、parkUntil时,就会进入该状态;
它和等待态一样,并不是因为请求不到资源,而是主动进入,并且进入后需要其他线程唤醒;
进入该状态后释放CPU执行权和占有的资源。
与等待态的区别:到了超时时间后自动进入阻塞队列,开始竞争锁。
终止态(TERMINATED)
线程执行结束后的状态。

8.2 分析死锁

在运行的程序中,通过命令窗口查看当前正在执行的线程id
jps
同通过jstack进行分析 :
jstack <vmid>



在输出的信息中,已经看到,发现了1个死锁,关键看这个 :

可以清晰的看到 :
Thread2 获取了<0x00000000f655dc50>的锁,等待获取<0x00000000f655dc40>这个锁
Thread1 获取了<0x00000000f655dc40>的锁,等待获取<0x00000000f655dc50>这个锁
由此可见,发生了死锁。
可以使用VisualVM工具进行JVM问题的排查

8.3 监控远程的jvm

VisualJVM不仅是可以监控本地jvm进程,还可以监控远程的jvm进程,需要借助于JMX技术实现。
8.3.1 什么是JMX?
JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架,JMX可以跨越一系列操作
平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用。
8.3.2 监控远程的tomcat
想要监控远程的tomcat,就需要在远程的tomcat进行对JMX配置,方法如下 :
#在tomcat的bin目录下,修改catalina.sh,添加如下的参数
JAVA_OPTS="
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmremote.ssl=false"
这几个参数的意思是 :
#-Dcom.sun.management.jmxremote : 允许使用JMX远程管理
#-Dcom.sun.management.jmxremote.port=9999 : JMX远程连接端口
#-Dcom.sun.management.jmxremote.authenticate=false : 不进行身份认证,任何用户都可以连接
#-Dcom.sun.management.jmremote.ssl=false : 不使用ssl
设置好以后保存,并重启tomcat
./startup.sh && tail -f ../logs/catalina.out : 重启tomcat并显示启动日志
通过VisualVM进行远程连接。
SpringBoot项目是内嵌的tomcat配置方式查看http://www.360doc.com/content/17/1018/20/16915_696185383.shtml

JVM史上最全实践优化没有之一的更多相关文章

  1. Tomcat8史上最全优化实践

    Tomcat8史上最全优化实践 1.Tomcat8优化 1.1.Tomcat配置优化 1.1.1.部署安装tomcat8 1.1.2 禁用AJP连接 1.1.3.执行器(线程池) 1.1.4 3种运行 ...

  2. 史上最全存储引擎、索引使用及SQL优化的实践

    史上最全存储引擎.索引使用及SQL优化的实践 1 MySQL的体系结构概述 2. 存储引擎 2.1 存储引擎概述 2.2 各种存储引擎特性 2.2.1 InnoDB 2.2.2 MyISAM 3. 优 ...

  3. 优秀后端架构师必会知识:史上最全MySQL大表优化方案总结

    本文原作者“ manong”,原创发表于segmentfault,原文链接:segmentfault.com/a/1190000006158186 1.引言   MySQL作为开源技术的代表作之一,是 ...

  4. Linux记录-史上最全的MySQL高性能优化实战总结(转载)

       史上最全的MySQL高性能优化实战总结! 1.1 前言 MySQL对于很多Linux从业者而言,是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰.在进行MySQL的优 ...

  5. JVM 内存溢出 实战 (史上最全)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  6. 史上最全的 Java 新手问题汇总

    史上最全的 Java 新手问题汇总   Java是目前最流行的编程语言之一——它可以用来编写Windows程序或者是Web应用,移动应用,网络程序,消费电子产品,机顶盒设备,它无处不在. 有超过30亿 ...

  7. 史上最全的spark面试题——持续更新中

    史上最全的spark面试题——持续更新中 2018年09月09日 16:34:10 为了九亿少女的期待 阅读数 13696更多 分类专栏: Spark 面试题   版权声明:本文为博主原创文章,遵循C ...

  8. Redis分布式锁 (图解-秒懂-史上最全)

    文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...

  9. SpringBoot面试题 (史上最全、持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

随机推荐

  1. python下载图片(2)

    #-*- coding: UTF-8 -*- import urllib2, re,datetime,time, os,sys from PIL import Image, ImageDraw, Im ...

  2. VCL to UniGUI Migration Wizard

    Free Evaluation Edition of The Automatic Migration Scripting Wizard For Converting Legacy Delphi Cod ...

  3. WPF实现弹幕

    实现效果 运用WPF的DoubleAnimation实现桌面端的弹幕效果 示例代码 https://github.com/zLulus/BarrageDemo

  4. GAC的一种非官方实现方式

    1.GAC简介 全局程序集缓存(Global Assembly Cache, GAC)计算机范围内的代码缓存,它存储专门安装的程序集,这些程序集由计算机上的许多应用程序共享.在全局程序集缓存中部署的应 ...

  5. C# GetFiles

    var path = AppDomain.CurrentDomain.BaseDirectory + "Images\\Rooms\\"; // string[] patterns ...

  6. 无法删除 NTFS 盘上的文件或文件夹(对Windows文件的各种情况有比较详细的描述)

    简介 本文介绍您可能无法删除 NTFS 文件系统卷上的文件或文件夹的原因,以及如何分析造成此问题的不同原因从而解决此问题. 更多信息 注意:在内部,NTFS 将文件夹作为特殊类型的文件进行处理.因此, ...

  7. PostgreSQL在win7上安装详细步骤

    原文:PostgreSQL在win7上安装详细步骤 PostgreSQL安装: 一.windows下安装过程 安装介质:postgresql-9.1.3-1-windows.exe(46M),安装过程 ...

  8. SQL Server Update:使用 TOP 限制更新的数据

    原文 使用 TOP 限制更新的数据 可以使用 TOP 子句来限制 UPDATE 语句中修改的行数.当 TOP (n) 子句与 UPDATE 一起使用时,将针对随机选择的 n 行执行删除操作.例如,假设 ...

  9. Go语言v1.8正式发布,有显著的性能提升和变化(go适合服务器编程、网络编程)

    前言 Go语言现在在服务端的网络编程领域越来越火,尤其像IM即时通讯应用这种富网络应用且对服务端网络性能要求极高的场景,很高兴看到Golang发布了1.8正式版,希望在多核架构横行的时代多一些这种顺应 ...

  10. HTTP.SYS 详解 (网络转载)

    http.sys 是一个位于Win2003和WinXP SP2中的操作系统核心组件, 能够让任何应用程序通过它提供的接口,以http协议进行信息通讯. 温馨提示:如果用户不慎删除了该驱动文件,不用担心 ...