JVM学习二

jvm监控排查问题相关工具:

jps、jstat、jinfo、jhat、jstack、jconsole、jmap、MAT、Btrace、psi_probe监控tomcat,通过gceasy查看和GCViewer查看GC,从而解决问题。

jps:查看所有的java进程

jps -help #显示jps所有的命令参数信息
jps #查看有哪些运行的java线程
jps -l  #输出主类的全名
jps -v #输出虚拟机启动时的jvm参数
jps -m #输出传递给java进程main()函数的参数

jstat:监视虚拟机各种运行状态信息:主要是查看类加载、垃圾回收、JIT编译、新生代、老年代等

jstat -help #显示jsta命令所有的参数信息
jstat -class vmid #显示ClassLoader的相关信息
jstat -compiler vmid #显示JIT编译的相关信息
jstat -gc vmid #显示与GC相关的堆信息
jstat -gcnew vmid #显示新生代信息
jstat -gcold vmid #显示老年代信息
jstat -gcnewcapcacity vmid #显示新生代大小使用情况
jstat -gcoldcapcacity vmid #显示老年代大小使用情况
jstat -gcutil vmid #显示垃圾收集信息
#当然也可以在里面加上时间和次数,以上如果不加时间和次数,默认打印一次,如:jstat -class vmid 时间 次数
jstat -gc vmid 时间 次数

jinfo:实时查看和调整虚拟机各项参数

jinfo -help #产看jinfo的相关命令参数信息
jinfo  -flag MaxHeapSize vmid #查看最大堆内存的大小
jinfo -flag UseConcMarkSweepGC vmid #查看垃圾回收器
jinfo -flag UserG1GC vmid #查看垃圾回收器
jinfo -flag +PrintGC vmid #开启查看GC打印日志信息

jhat:分析heapdump文件,在浏览器上查看分析结果

jhat -help #查看jhat所有命令参数信息
jhat C:\Users\Administrator\Desktop\heap.hprof

jstack:生成虚拟机当前时刻的线程快照,可以进行日志分析,定位线上问题。

死锁:A线程和B线程相互获取资源,都在等待对方,导致死锁

public class DeadLockDemo {    private static Object resource1 = new Object();//资源 1    private static Object resource2 = new Object();//资源 2
    public static void main(String[] args) {        new Thread(() -> {            synchronized (resource1) {                System.out.println(Thread.currentThread() + "get resource1");                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println(Thread.currentThread() + "waiting get resource2");                synchronized (resource2) {                    System.out.println(Thread.currentThread() + "get resource2");                }            }        }, "线程 1").start();
        new Thread(() -> {            synchronized (resource2) {                System.out.println(Thread.currentThread() + "get resource2");                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println(Thread.currentThread() + "waiting get resource1");                synchronized (resource1) {                    System.out.println(Thread.currentThread() + "get resource1");                }            }        }, "线程 2").start();    }}

由于两者之间相互等待,所以运行时间很长,程序没有结果,因此可以通过查看进程jps拿到程序的进程信息,从而通过jstack 进程id,从而获取详细的日志信息。

jdk可视化工具分析:jconsole,内存监控和线程监控

可进行远程监控,方便线上排查问题

如果需要使用 JConsole 连接远程进程,可以在远程 Java 程序启动时的配置文件上加上下面这些参数:

-Djava.rmi.server.hostname=外网访问 ip 地址
-Dcom.sun.management.jmxremote.port=60001 //监控的端口号-Dcom.sun.management.jmxremote.authenticate=false   //关闭认证-Dcom.sun.management.jmxremote.ssl=false

在使用 JConsole 连接时,远程进程地址如下:

外网访问 ip 地址:60001 

连接好就可以查看监控信息了

jmap:生成堆转储快照

jps -l  #拿到pid信息
jmap -dump:format=b,file=heap.hprof pid #b表示二进制,生成文件heap.profjmap -heap pid #内存区块信息

此时可以配合MAT分析内存溢出的信息,导入映像文件,进行查看。

java线程的状态:

NEW:线程还没开始

WAITING:等待状态

RUNNABLE:运行状态

TIMED_WAITING:限时等待

BLOCKING:阻塞等待状态

TERMINATED:终止退出

基于jvisualvm的可视化监控:

监控本地tomcat、监控远程tomcat、监控普通java进程等都可以。

监控远程tomcat,需要修改tomcat的配置文件catalina.sh添加如下信息:

JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9004 -Dcom.sun.management.jmxremote.anthenticate=false -Dcom.sun.management.jmxremote.jmxremote.ssl=false -Djava.net.preferIPV4Stack=true -Djava.rmi.server.hostname=10.19.10.10"

添加完连接信息之后,就可以进行jmx连接了。

监控远程tomcat:

基于Btrace的监控调试,Btrace可以动态地向母亲应用程序的字节码注入跟踪代码。

javaComplierApi:JVMTI、Agent、Instrumentation+ASM

Btrace安装:

新建环境变量,添加path.,类似eclipse。

两种运行脚本方式:在jvisualvm添加Btrace插件,添加classpath,类似配置jconsole.

使用命令行btrace<pid> <trace_script>

三个jar包引入pom文件:Btrace-agent.jar、Btrace-boot.jar、Btrace-client.jar

@Btrace注解:

@OnMethod(clazz="com.study.mt.testController",
          method="arg1",
          localtion=@Localtion(kind.ENTRY))

命令:

jps -l
btrace pid printArgSimple.java

可以采用命令启动,也可以在jvisualvm中使用

Btrace使用:

拦截方法:

普通方法,@OnMethod(clazz=" ",method=" ")
构造方法:@OnMethod(clazz="",method="<init>")
拦截同名函数,用参数区分

拦截时机:入口、运行、结束等

kind.Entry:入口,默认值
kinf.RETURN:返回
kind.THROW:异常
kind.LINE=行

异常吞掉也没关系,BTrace也可以追踪,方便排查问题

BTrace只能本地运行,如果需要远程连接,则需要修改源代码

拦截this、参数、返回值:

this:@self
入参:可以用AnyType,也可以用真实类型,同名的用真实的
返回值:@return

其他:获取对象的值

简单类型:直接获取
复杂类型:发射、类名+属性名

注意:生产环境下使用,需要注意被修改的字节码不会被还原

tomcat性能调优:首先需要修改tomcat的配置文件:tocat-user.xml、添加manager.xml:

tocat-user.xml添加几个角色信息:

<role rolename="tomcat"/>
<role rolename="manager-status"/>
<role rolename="manager-gui"/>
<role username="tomcat" password="tomcat" 
   roles="tomcat,managet-status,managet-gui"/>

manager.xml配置如下信息:

<context provileged="true" antiResourceLock="false"
     docBase='${catalina.home}/webapps/manager'>
   <Valve className=
"org.apache.catalina.valves.RemoteAddrValve"
        allow="^192.168.*$" />
</Context>        

访问远程tomcat的管理页面,可以在server.status中查看到jvm参数信息。

除了使用tomcat的管理页面看到tomcat的jvm信息之外,还可以通过psi_probe监控看到相关参数信息,需要配置tomcat-user.xml和manager.xml的配置,放入到tomcat下面即可。

本文分享自微信公众号 - 后端技术学习(gh_9f5627e6cc61),作者:亚洲

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • JVM学习一

    jvm的内存结构:可以看到我们的java文件会首先编译成class文件,经过类加载器进行加载,然后经过jvm的相关区域:f方法区、堆、虚拟机栈、程序计数器、本地...

    路行的亚洲
  • HashMap源码学习

    首先实现map的子类:HashMap、HashTable、TreeMap、LinkedHashMap。

    路行的亚洲
  • RocketMQ的NameServer执行流程学习梳理

    首先NamesrvStartUp启动,首先经过main()方法,也是我们常见的main方法进入到main0()执行创建controller操作与启动contro...

    路行的亚洲
  • uni-app 网络请求

    若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。

    达达前端
  • Redis源码解析——内存管理

            在《Redis源码解析——源码工程结构》一文中,我们介绍了Redis可能会根据环境或用户指定选择不同的内存管理库。在linux系统中,Redis...

    方亮
  • 等级保护2.0标准解读——等保2.0与1.0的区别

    重新对定级对象进行调整,并进行相应的介绍。2。0定级对象分为基础信息网络、信息系统和其他信息系统。其中信息系统再细分为工业控制系统、物联网、大数据、移动互联以及...

    牛油果
  • 深度强化学习-Policy Gradient基本实现

    在之前的几篇文章中,我们介绍了基于价值Value的强化学习算法Deep Q Network。有关DQN算法以及各种改进算法的原理和实现,可以参考之前的文章: 实...

    石晓文
  • 计算机视觉中的注意力相关论文

    1、The Application of Two-level Attention Models in Deep Convolutional Neural Net...

    绝命生
  • SAP SD模块常用bapi函数

    BAPI_OUTB_DELIVERY_READ_SLS根据销售订单创建交货单,得到交货单创建初始页面所需的数据

    用户5495712
  • iOS开发·runtime原理与实践: 消息转发篇(Message Forwarding) (消息机制,方法未实现+API不兼容奔溃,模拟多继承)

    在我们开始使用消息机制之前,我们可以约定我们的术语。例如,很多人不清楚“方法”与“消息”是什么,但这对于理解消息传递系统如何在低级别工作至关重要。

    陈满iOS

扫码关注云+社区

领取腾讯云代金券