# jvm基础01

jvm基础01


1. jvm参数

1.1 jvm运行参数

    1. 标准参数 ,以-开头设置参数,可以用java -help 查看标准参数

java -help|showversion|version|server|client

  • 2.非标准参数-X,以-X开头,可以用java -X查看参数

java -Xint|Xcomp|Xmixed

  • 3.-XX参数,以-XX:开头,主要用于jvm的调优和debug操作

java -XX:newSize|+UseSerialGC|newRatio=1


1.2 -server与-client参数


    1. 初始化堆空间

ServerVM的初始堆空间会大一些,默认使用的是并行垃圾回收器,启动慢运行快。
ClientVM相对来讲会保守一些,初始堆空间会小一些,使用串行的垃圾回收器,
它的目标是为了让JVM的启动速度更快,但运行速度会比Serverm模式慢些。

    1. JVM在启动的时候会根据硬件和操作系统自动选择使用Server还是Client类型的JVM。

32位操作系统如果是Windows系统,不论硬件配置如何,都默认使用Client类型的JVM。
如果是其他操作系统上,机器配置有2GB以上的内存同时有2个以上CPU的话默认使用server模式,否则使用client模式。

64位操作系统只有server类型,不支持client类型。

    1. 执行命令: java‐server‐showversion TestJVM

1.3 执行模式

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

强制设置运行模式

#强制设置为解释模式
[root@node01test]#java ‐showversion ‐Xint TestJVM
#强制设置为编译模式
[root@node01test]#java ‐showversion ‐Xcomp TestJVM
#默认的混合模式[root@node01test]#java ‐showversion TestJVM

1.4 jvm常用查看堆的参数

#-Xms与-Xmx,-Xmn分别是设置jvm的堆内存的初始大小和最大大小,最小大小
#-Xmx2048m:等价于-XX:MaxHeapSize,设置JVM最大堆内存为2048M。
#-Xms512m:等价于-XX:InitialHeapSize,设置JVM初始堆内存为512M。
[root@node01test]#java ‐Xms512m ‐Xmx2048m TestJVM

#查看jvm的运行参数
#1.运行java命令时打印参数
java‐XX:+PrintFlagsFinal ‐XX:+VerifySharedSpaces ‐version

#2.查看正在运行的jvm参数
#查看某一参数的值,用法:jinfo‐flag<参数名><进程id>
[root@node01bin]#jps -l #查看进程id
[root@node01bin]#jinfo ‐flag MaxHeapSize 6219

2. jvm内存模型


2.1 jvm内存区


    1. jdk1.7的内存模型

jvm运行时内存为:Eden区+2*Survivor区+OldGen区+Perm区 即是新生代和老年代,永久代的总和

    1. jdk1.8的内存模型

jvm运行时内存为:Eden区+2*Survivor区+OldGen区+MetaSpaces 即是新生代和老年代,元空间的总和
jdk1.8时,移除了永久代,因为JRockit VM虚拟机并不支持永久代,为了同时兼容HotSpot VM和JRockit VM虚拟采用元空间MetaSpaces来代替,此时的元空间不再受虚拟机的内存限制,而是直接受本地电脑内存的限制,从而大大地避免oom现象。

2.2 jvm堆内存模型


  • 新生代(Eden区+2*Survivor区)

Young区被划分为三部分,Eden区和两个大小严格相同的Survivor区,其中,Survivor区间中,某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用,在Eden区间变满的时候,GC就会将存活的对象移到空闲的Survivor区间中,根据JVM的策略,在经过几次垃圾收集后,任然存活于Survivor的对象将被移动到Tenured区间

  • 老年代(OldGen区)

Tenured区主要保存生命周期长的对象,一般是一些老的对象,当一些对象在Young复制转移一定的次数以后,对象就会被转移到Tenured区,一般如果系统中用了application级别的缓存,缓存中的对象往往会被转移到这一区间。

  • 永久代(Perm区)

Perm代主要保存class,method,filed对象,这部份的空间一般不会溢出,除非一次性加载了很多的类,不过在涉及到热部署的应用服务器的时候,有时候会遇到java.lang.OutOfMemoryError:PermGenspace的错误,造成这个错误的很大原因就有可能是每次都重新部署,但是重新部署后,类的class没有被卸载掉,这样就造成了大量的class对象保存在了perm中,这种情况下,一般重新启动应用服务器可以解决问题。

  • Virtual区

最大内存和初始内存的差值,就是Virtual区

2.3 查看堆内存使用情况

  • jstat命令可以查看堆内存各部分的使用量,以及加载类的数量
[root@node01~]#jps #查看进程ID
# jstat[-命令选项][vmid][间隔时间/毫秒][查询次数]:
#1:查看class加载统计
[root@node01~]#jstat ‐class 6219
Loaded Bytes Unloaded Bytes Time 
3273	7122.3 	0 	0.0	3.98
  • Loaded:加载class的数量Bytes:所占用空间大小Unloaded:未加载数量Bytes:未加载占用空间Time:时间
#2:查看编译统计
[root@node01~]# jstat ‐compiler 6219

说明:

  • Compiled:编译数量。
  • Failed:失败数量
  • Invalid:不可用数量
  • Time:时间
  • FailedType:失败类型
  • FailedMethod:失败的方法
#3:垃圾回收统计
[root@node01~]# jstat ‐gc 6219
#也可以指定打印的间隔和次数,每1秒中打印一次,共打印5次
[root@node01~]#	jstat	‐gc	62191	000 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:垃圾回收消耗总时间
  • jmap的使用以及内存溢出分析

[root@node01~]#jps #查看进程ID
#1:查看内存使用情况(NewRatio,SurvivorRatio,NewRatio)
[root@node01~]# jmap ‐heap 6219
#2:查看内存中对象数量及大小
#查看所有对象,包括活跃以及非活跃的
[root@node01~]# jmap ‐histo<pid>|more
#查看活跃对象
[root@node01~]# jmap ‐histo:live <pid> | more
[root@node01~]# jmap ‐histo:live 6219 |more
num  #instances #bytes class  name
........

#3:将内存使用情况dump到文件中
#示例
[root@node01~]# jmap‐dump:format=b,file=/tmp/dump.dat 6219
....

#4:通过jhat对dump文件进行分析
[root@node01~]#  jhat‐port9999/tmp/dump.dat

  • jstack的使用查看正在运行的jvm的线程情况

查看下jvm中的线程执行情况,比如,发现服务器的CPU的负载突然增高了、出现了死锁、死循环等
[root@node01bin]#jstack2203


  • VisualVM工具的使用

VisualVM,能够监控线程,内存情况,查看方法的CPU时间和内存中的对象,已被GC的对象,反向查看分配的
堆栈(如100个String对象分别由哪几个对象分配出来的)。VisualVM使用简单,几乎0配置,功能还是比较丰富的,几乎囊括了其它JDK自带命令的所有功能。

  • 内存信息线程信息
  • Dump堆(本地进程)
  • Dump线程(本地进程)
  • 打开堆Dump。堆Dump可以用jmap来生成。
  • 打开线程Dump
  • 生成应用快照(包含内存信息、线程信息等等)
  • 性能分析。CPU分析(各个方法调用时间,检查哪些方法耗时多),内存分析(各类对象占用的内存,检查哪些类占用内存多)
#启动方式 进入jdk的安装目录的bin目录下,找到jvisualvm.exe
[root@node01~]# jvisualvm # 可以看到对应的jvm对信息和参数
  • 监控远程的jvmVisualJVM

VisualJVM不仅是可以监控本地jvm进程,还可以监控远程的jvm进程,需要借助于JMX技术实现
JMX(JavaManagementExtensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。
JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用

  • 监控远程的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.jmxremote.ssl=false" 
#这几个参数的意思是:
#‐Dcom.sun.management.jmxremote:允许使用JMX远程管理
#‐Dcom.sun.management.jmxremote.port=9999:JMX远程连接端口
#‐Dcom.sun.management.jmxremote.authenticate=false:不进行身份认证,任何用户都可以连接
#‐Dcom.sun.management.jmxremote.ssl=false:不使用ssl

使用VisualJVM连接远程tomcat: 连接远程主机:ip:9999

原文地址:https://www.cnblogs.com/yiyangyu/p/jvm001.html