一. 背景
写代码和线上维护时,调试功能是必不可少的,经常在应用程序启动脚本中看到如下配置:
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指令即可。
相关推荐
本示例代码集合旨在提供一个实践平台,帮助开发者掌握JVM调试技巧。我们将探讨以下几个关键知识点: 1. **JVM内存模型** - Java内存分为堆内存、栈内存、方法区、程序计数器和本地方法栈。理解它们的作用是调试的...
此外,随着JVM技术的发展,不断有新的特性被加入,因此,阅读官方文档、参与社区讨论、实践调试和性能分析等方法,也是学习JVM不可或缺的途径。开发者需要通过阅读和实践相结合,不断积累经验,才能深入掌握JVM...
### 深入学习JVM(Java虚拟机)内核教程知识点详解 #### 1. JVM运行机制 - **概述**:JVM是Java程序在计算机上运行的基础平台,它负责将Java字节码转换为特定平台上的机器指令并执行。 - **主要组件**: - **类...
### 深入JVM内核:原理、诊断与优化 #### 一、JVM基础知识 **1.1 JVM概念** Java虚拟机(Java Virtual Machine,简称JVM)是一种用于执行Java字节码的虚拟机。它为Java程序提供了一个运行环境,能够独立于硬件平台...
深入理解JVM虚拟机机制是Java开发者必备的技能之一。...通过学习JVM的内部工作原理,开发者可以更好地调试代码,优化内存使用,以及解决各种运行时问题,从而编写出更高效、更稳定的Java应用程序。
通过深入学习这本书,开发者可以提升对Java程序运行机制的洞察力,从而更好地进行性能调优和问题排查。 1. **JVM架构**:JVM是Java平台的核心组成部分,它负责执行字节码,提供了一个跨平台的运行环境。JVM包括类...
通过深入学习JVM,开发者不仅可以提高代码质量,还能有效地解决性能问题,提升系统的稳定性和可靠性。《深入JAVA虚拟机》这本书提供了丰富的实践案例和深入的理论解析,是每个Java开发者必备的参考资料。
### 深入JVM内核—原理、诊断与优化 #### 一、JVM基础知识 ##### 1.1 JVM概念 ...以上内容仅为概述,具体细节还需要结合实际场景进行深入学习和实践。希望本教程能够为读者提供有价值的指导和帮助。
手册前言部分强调了对JVM体系结构的深入理解是性能调优的前提。在这个基础上,通过实例(example)的实践来巩固和验证理论知识。生产环境的复杂性要求开发者必须具备高度的实践能力,本手册可以作为学习和参考资料。...
《深入理解Java虚拟机》是Java开发者...因此,无论是初级还是高级Java开发者,都应该把学习JVM作为一项重要的技术积累。通过阅读《深入理解Java虚拟机》,我们可以系统地掌握JVM的各个方面,从而提升我们的专业水平。
### 深入解析JVM:Java...总之,JVM不仅是Java程序员的基础功底,更是优化和调试Java应用的强大工具。掌握JVM的原理和实践,能够显著提升应用程序的稳定性和效率,对于从事Java开发的专业人士而言,是不可或缺的能力。
开源项目“jvmjava”为开发者提供了一种学习JVM内部运作方式的途径。通过阅读和分析源代码,我们可以了解JVM的各个组件,如类加载器、运行时数据区、字节码解释器、垃圾收集器等。这不仅有助于提升Java编程技能,还...
这些内容可以作为学习Java虚拟机的基础材料,帮助初学者快速入门,并为之后的深入学习打下坚实的基础。需要注意的是,JVM的学习是需要与实践相结合的,只有通过不断的实验和调优,才能更好地掌握和应用这些知识。
- **src.zip**:包含了JVM的源代码,供开发者进行深入学习和调试。 - **bin**:目录下包含可执行文件,如`java.exe`,这是运行Java应用程序的命令行工具。 - **include**:包含了头文件,供开发人员使用C或C++...
《JVM虚拟机深度讲解》这本书是JAVA开发者深入理解JVM的重要参考资料,它全面而详尽地探讨了Java虚拟机的工作...通过深入学习,开发者不仅可以理解JVM的工作机制,还能提升编程技能,解决实际问题,达到技术上的突破。
通过深入学习《JVM8虚拟机规范》,开发者可以更好地理解Java程序的运行机制,提高代码质量,有效避免内存泄漏、性能瓶颈等问题,从而提升应用的整体性能和稳定性。无论是开发、调试还是优化,对JVM的深入理解都是必...
`src`目录可能包含了实现模拟JVM的源代码,这将是一个深入学习JVM原理的好资源。 5. **readme.txt** 这个文件可能是关于模拟项目的介绍或使用指南,包含如何构建和运行模拟JVM的步骤,以及可能遇到的问题和解决...
《深入理解JVM的源代码》是周志明先生的一部深度解析Java虚拟机(JVM)的经典著作。这本书以源代码为线索,...通过对源代码的深入学习,我们可以更好地理解和应对各种编程挑战,从而编写出更加健壮、高效的Java应用。