JVM调优

JVM优化概述

略!

JVM参数----待完善

JVM参数类型

  • 标准参数

    如:-help, -version,这种直接使用中划线带上的参数,就是标准参数。

    java -help命令可以查看所有的标准参数

  • -X参数

    称为非标准参数,意味着后续的JDK版本中可能会变化,而且变化了,Oracle官方也可能不会给任何的通知。

    java -X命令可以查看所有的-X参数

    常用的几个-X参数,如下:

    -Xint		interpreted  JVM运行,使用解释模式
    -Xcomp		compile		 JVM运行,使用编译模式
    -Xmixed					JVM运行,使用混合模式,JVM的默认运行模式,也是推荐使用的模式
    

    JVM运行模式

  • -XX参数

    使用率高,主要用于JVM参数调优,以及debug操作。

1568961558112

查看正在运行的JVM参数:jinfo命令

命令格式:jinfo -falgs <进程id>

# 查询tomcat运行的进程id
# 方式1
ps -ef | grep tomcat 
# 方式2
jps -l	# JVM提供的查询进程信息的指令

# 查询进程信息
jinfo -flags 9552 # 9552是某个运行中的tomcat的进程id。  可能会有多个tomcat进程在运行。

查看JVM进程信息,还可以使用如下的命令:

java -XX:+PrintFlagsFinal -version

JVM内存模型

JDK1.7与JDK1.8,JVM内存模型存在较大的差异。

JDK1.7中的JVM内存模型

1568962987798

  • Young 年轻代

    • Eden

    • S0 通常称为from survivor

    • S1 通常称为to survivor

      S0区与S1区是大小相同的。

  • Tenured 年老代

    缓存中的对象往往会被转移到此区域去。

  • Perm 永久代

    此区域主要保存class,method, filed对象,这部分空间一般不会出现内存溢出,除非一次加载了很多的类。实际中可能出现的情况:

    在涉及到热部署的应用服务器时,有时会遇到java.lang.OutOfMemoryError:PermGen space的错误,这很可能是因为每次重新部署时,原来的类文件没有被卸载掉,这样就会造成大量的class对象保存在了perm区中,引发内存溢出。

    解决方案:重启应用服务器。

    通常也不会出现GC过程。

  • Virtual 虚拟区

    JVM堆最大内存与初始内存的差值,就体现在Virtual区。

JDK1.8中的JVM内存模型

1568963287236

注意:

Metaspace区所占用的内存空间不是在虚拟机内部,而是在本地内存空间中,这是JDK1.8与JDK1.7的JVM内存模型最大的区别所在。(Perm Area --> Metaspace Area)

细化出来,如下:

1568964047755


1568973318352

jstat命令

命令格式:jstat <-命令选项> <vmid> [时间间隔/ms] [查询次数]

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

参数说明:

  • vmid Virtual Machine Identifier JVM进程id

查看类加载情况

查看tomcat中的类加载情况,运行的tomcat就是一个JVM进程。

# 查看tomcat进程id
jps -l

# 查看类加载情况
jstat -class 9552 # 9552是其中一个tomcat进程的id号

查看编译情况

# 查看tomcat进程id
jps -l

# 查看进程中类的编译情况
jstat -compiler 9552 # 9552是其中一个tomcat进程的id号

查看垃圾回收情况

# 查看tomcat进程id
jps -l

# 查看进程中类的编译情况
jstat -gc 9552 # 9552是其中一个tomcat进程的id号

1568965245872

jmap命令

可以查看更详细的信息

命令格式:

jmap [-option] <pid>
	(to connect to running process)
jmap [-option] <executable <core>
	(to connect to a core file)
jmap [-option] [server_id@]<remote server IP or hostname>
	(to connect to remote debug server)

查看heap区使用情况

# 查看tomcat进程id
jps -l

# 查看进程中类的编译情况
jmap -heap 9552 # 9552是其中一个tomcat进程的id号

查看JVM内存中的对象数量与大小

  • jmap -histo <pid> 查看所有对象
  • jmap -histo:live <pid> 查看活跃对象(或者说是存活对象)
# 查看tomcat进程id
jps -l

# 查看进程中类的编译情况
jmap -histo 9552 | more # 加个管道命令,分页查看。不然一次显示太多内容,看不过来。

将JVM内存使用情况,dump到磁盘文件中

# dump: 转存		-dump,是jmap命令的一个命令选项
jmap -dump:format=b,file=/test/dump.dat 9952 
# 将进程id=9952的JVM内存使用情况,以二进制格式保存到`/test/dump.dat`文件中

某个进行的JVM内存使用情况,保存到磁盘文件后,就需要对其进行分析,以下介绍两种分析手段:

  • jhat命令:

    命令格式:jhat -port <端口号> <file>

    file:文件的全路径名,如/test/dump.dat

    指定端口后,这个命令会将指定的Heap Dump文件进行解析,并在指定的端口上生成一个web应用,然后可以通过浏览器去访问,如:192.168.178.131:9999。里面可以查看到上面指定的进程的JVM内存使用情况。

    OQL查询语言: Object Query Language

    ​ 浏览器访问上述解析结果的程序时,在其页面的最后,会有这个 对象查询语言

  • MAT工具

    Memory Analyzer Tool,它是一款基于Eclipse的内存分析工具。这是一款可视化工具。

实战:模拟死锁,并使用jstack命令查看程序

编写死锁的代码

以下代码可以模拟“死锁”。

使用命令行去运行以下的代码,出现死锁后,程序将没有任何反应。

public class DeadLockTest {

    private static Object obj1 = new Object();
    private static Object obj2 = new Object();
    
    public static void main(String[] args) {
        new Thread(new Thread1()).start();
        new Thread(new Thread2()).start();
    }

    private static class Thread1 implements Runnable{
        @Override
        public void run() {
            synchronized (obj1){
                System.out.println("Thread1拿到了obj1对象的锁!");

                try {
                    // 让Thread1停顿2s的目的,是让Thread2去拿到obj2的锁
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (obj2){
                    System.out.println("Thread1拿到了obj2对象的锁!");
                }
            }
        }
    }

    private static class Thread2 implements Runnable{
        @Override
        public void run() {
            synchronized (obj2){
                System.out.println("Thread2拿到了obj2对象的锁!");

                try {
                    // 让Thread2停顿2s的目的,是让Thread1去拿到obj1的锁
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (obj1){
                    System.out.println("Thread2拿到了obj1对象的锁!");
                }
            }
        }
    }

}

运行代码

将代码放到Linux中运行。

  • 在根目录/下新建一个test目录,并创建一个java类文件DeadLockTest

  • 使用EditPlus,编辑.java文件

    • 将上述代码复制到其中

    • 修改文件的编码为UTF-8

      • 文档 --> 文本编码 --> 转换文本编码,选择UTF-8

      不修改编码,没法运行。

  • 进入到/test目录中,执行以下java命令,运行程序

javac DeadLockTest.java # 编译
java DeadLockTest # 运行

​ 一运行程序,程序就会进入死锁状态,表现出来的情况就是程序没任何反映了。

使用jstack命令查看程序运行情况

jstack命令的格式:jstack <vmid>

  • 克隆一个命令窗口

  • 使用jstack命令查看

    # 查看当前运行的进程情况
    jps -l
    
    # 查看
    jstack 10955 # 10995是DeadLockTest程序所使用的端口
    

    1568971866980


1568972060526

总结

这样,如果程序出现了没有任何反应的情况,就能够通过jstack命令查看到到底发生了什么!

Java VisualVM工具

它是JDK自带的一款功能强大的可视化JVM内存分析工具
1568975756906

它可以监控本地进行的JVM内存,也可以监控远程JVM进程(这是非常非常有用的,因为实际中,应用都是部署在远程服务器上的)。

1568975343950



  • 以管理员身份直接运行exe文件即可打开此工具!

1568975493051


监控本地JVM

进入"本地"–> "VisualVM"中即可 查看。

监控远程JVM

这个需要远程主机进行配置,并在本地通过Java VisualVM去连接远程主机。

这项功能,需要借助于一款工具:JMT

JMT工具

JMT(Java Management Extensions, Java管理扩展工具),它是一个为应用程序、设备、系统等植入管理功能的框架。JMT可以跨越异构的操作系统(如本地主机是windows系统,远程主机是Linux系统,它也可以进行远程连接)、系统体系结构和网络传输协议,灵活地开发无缝集成的系统、网络与服务管理应用。

远程主机配置

以监控远程的Tomcat程序为例!

需要在tomcat的bin目录下,修改JVM配置文件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安全协议进行传输信息加密

修改配置文件后,重启Tomcat。

# 使用tail命令来查看tomcat启动日志
# 进入到tomcat的bin目录下
./startup.sh && tail -f ../logs/catalina.out

本地连接远程主机

在Java VisualVM中进行配置如下:

1568977419421


在这个地方,可能有的人能够连接上,有的人连接不上。
我就连接不上,具体原因还在研究之中。。。。。。
QQQQ: 出现问题了

  • JMX远程连接不上
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值