`

深入学习jvm调试

阅读更多

 

一. 背景

写代码和线上维护时,调试功能是必不可少的,经常在应用程序启动脚本中看到如下配置:

JAVA_DEBUG_OPT=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=9108,server=y,suspend=n "

  

这几参数中,对address相对熟悉一点,因为线上要修改端口号吐舌头,而其他几个参数就不知道什么意思了。今天深入学习了一下,分享给大家。

 

二. 每个参数的含义

-Xdebug

让jvm在调试模式下运行,必须开启。

-Xnoagent

禁用默认的sun默认的调试器。 --- 这个参数最不解,找了很多文章,也没有解决我的疑惑,希望了解的人告诉我下哈酷

-Djava.compiler=NONE

禁止jvm加载JIT编译器。考虑到debug模式下都是一条一条执行指令,使用JIT效率会更低,因此禁用掉。具体的原因有点复杂,具体请看下面。

-Xrunjdwp:transport

让jvm加载jdwp(java debug wire protocol,java调试网络协议)的实现。通过jdwp,调试器和jvm进行通信。这个参数后面有一系列的参数,如transport、address等。

transport

协议传输方式,dt_sorket表示使用套接字进行传输。据说,win平台可以使用共享内存传输,没有试过。

server

debug需要调试器(eclipse是一种调试器)和目标应用程序(待调试的程序)协同工作,这样才能有效调试,因此,调试链路有两个节点:调试器和目标应用程序。这两个节点都可以作为服务端,等待对方的连接,该参数就是控制究竟哪一方作为服务端的。该参数有两种取值:

y:目标应用程序作为服务端,这是我们最常用的方式。应用程序开启debug模式,启动应用,然后调试器(eclipse)进行连接。

n:调试器作为服务端。我没有使用过这种方式,用的也不多。使用这种方式,调试器首先要开启一个listener,然后目标应用程序启动,最后,两者连接起来。 

address

套接字传输的端口号,这个参数你也最熟悉了吧,因为改的最多。

suspend

是否延迟加载jvm。这个参数也有点重要,有两个取值:

y:运行程序启动脚本后,发现jvm会暂停,直到调试器连接过来后,jvm会继续加载。一般,类的init的方法在加载时运行,你可以通过设置suspend=y来调试init方法,比如filter的init方法等。

n:运行程序启动脚本后,jvm自动加载,然后开启debug端口号。调试器随时连接到jvm。一般都会使用这种方式。

三. 一些调试技巧

3.1 类的init方法通常在加载时运行,如何调试?

修改debug参数,修改suspend=y,重启应用程序。这样,只有调试器连接应用程序后,jvm才会继续加载。

3.2 如何修改debug端口号?

有时碰到端口冲突的问题,修改address参数即可。

四. 为什么设置-Djava.compiler=NONE

设置目的:禁止使用JIT转义器,加快debug的速度。

 

jvm在执行class文件时,会将java字节码转换成本地机器码,有两种利器:JIT和转义器(interpreter)。

转义器(interpreter):每次执行class文件,jvm都会将字节码转换成微指令,然后按照顺序依次执行,有时一个java指令会被转义成十几个微指令。因此执行效率非常低。

JIT:针对interpreter的瓶颈,JIT技术在第一次执行class文件时,对其进行一次编译,会被精简成原生态指令码。经过一次编译后,下次再执行相同的class时,就不需要编译了。因此,对频繁执行的class使用JIT技术进行转义,整体执行效率会非常高。PS:由于第一次执行时,要进行彻底转义,因此会非常耗时。

因此,interpreter和JIT各有优缺点:

interpreter:针对执行次数极少的class文件,interpreter性能更好。

JIT:对于频繁执行的class文件,JIT技术更优。

 

学习完interpreter和JIT后,回到debug模式下为什么要关闭JIT?一般来说,debug模式下,都是执行几行代码,不会频繁执行某一个class。因此为了提高debug的速度,一般把JIT关闭,使用interpreter转义java指令即可。

分享到:
评论

相关推荐

    【Java面试+Java学习指南】一部分大部分Java招聘所需要掌握的核心知识

    深入浅出JVM JVM内存模型 性能调优、线上问题排查 类加载机制详解 垃圾回收机制 垃圾回收器、垃圾回收算法 ARM与多线程 多线程基础知识 常见关键字 多线程锁机制 线程池知识点 常见的JUC工具类 多线程经典面试题 ...

    HotSpot实战

    《HotSpot实战》深入浅出地讲解了HotSpot虚拟机的工作原理,将隐藏在它内部的本质内容逐一呈现在读者面前,包括OpenJDK与HotSpot项目、编译和调试HotSpot的方法、HotSpot内核结构、Launcher、OOP-Klass对象表示系统...

    java版飞机大战源码-java-club:Java程序员所需要掌握的核心知识都在这里。。。。alittledaily~

    深入浅出JVM JVM内存模型 性能调优、线上问题排查 类加载机制详解 垃圾回收机制 垃圾回收器、垃圾回收算法 并发与多线程 线程状态转换与通信机制 线程同步与互斥 线程池知识点 常见的JUC工具类 常用工具集 JVM问题...

    Hadoop实战(第2版)

    技术点79 MapReduce 函数、作业和管道的单元测试13.1.3 LocalJobRunner...调试JVM 配置技术点83 解决任务的JVM 启动参数13.2.4 高效调试的编码准则技术点84 调试和错误处理13.3 MapReduce 陷阱技术点85 ...

    java8集合源码-learn-java:学习Java

    Box:设计、编码、调试和使用。 51 小时。 参加者先决条件 培训«1。 Java 应用程序构建» 完成 培训目标 本地化和修复深层构建时错误的实践技能 运行时JVM参数化的实践技巧 深入了解 Java 语法细节 理解系统设计...

    Hadoop实战(陆嘉恒)译

    编程实践6.1 开发MapReduce 程序6.1.1 本地模式6.1.2 伪分布模式6.2 生产集群上的监视和调试6.2.1 计数器6.2.2 跳过坏记录6.2.3 用IsolationRunner重新运行出错的任务6.3 性能调优6.3.1 通过combiner来减少网络流量...

    Hadoop实战中文版

    5.5 小结 5.6 更多资源 第6章 编程实践 6.1 开发MapReduce 程序 6.1.1 本地模式 6.1.2 伪分布模式 6.2 生产集群上的监视和调试 6.2.1 计数器 6.2.2 跳过坏记录 6.2.3 用IsolationRunner重新运行出错的任务...

    Eclipse开发分布式商城系统+完整视频代码及文档

    │ │ 深入理解Java内存模型.pdf │ │ │ └─课后资料 │ ├─笔记 │ │ 淘淘商城_day20_课堂笔记.docx │ │ │ └─视频 │ 07-使用Jedis连接集群操作.avi │ 00-今日大纲.avi │ 01-RDB持久化方式.avi │ 02...

    Hadoop实战

    1105.5 小结 1115.6 更多资源 112第6章 编程实践 1136.1 开发MapReduce程序 1136.1.1 本地模式 1146.1.2 伪分布模式 1186.2 生产集群上的监视和调试 1236.2.1 计数器 1236.2.2 跳过坏记录 1256.2.3 用...

    Hadoop实战中文版.PDF

    1186.2 生产集群上的监视和调试 1236.2.1 计数器 1236.2.2 跳过坏记录 1256.2.3 用IsolationRunner重新运行出错的任务 1286.3 性能调优 1296.3.1 通过combiner来减少网络流量 1296.3.2 减少输入数据量...

Global site tag (gtag.js) - Google Analytics