使用java 做开发,大部分的朋友都是利用DIE 来做debug 工作,因为这样可视化效果好。

但是在真实的工作中,很多使用遇到问题,手头或者环境是不允许你利用DIE 来对源码做debug 工作,开发者只能够利用仅有的jdk 环境和shell 环境,对出现问题的程序进行debug。

本篇文章主要是向大家介绍,如何利用jdk 自带的 jdb 和jstack 来定位问题。

  • jdb

首先jdb 是一款类似gdb 的工具,它可以帮助用户在运行程序时,直接打对应断点,然后进行debug 工作。

jdb 和IDE debug 的区别在于,整个debug 过程都是命令行交互的。

用户使用jdb 进行debug ,有两种方式

  1. 直接利用jdb 启动程序
  2. 在启动程序时,加入特殊参数,使得用户可以通过 jdb attach 进去

我们先来看看直接使用jdb 如何debug 程序。

jdb 运行程序,其实和java 直接运行程序差不多,但是有一些小细节需要大家注意的,就是jdb 不支持-cp 命令,也不支持以下方式添加classpath

-Djava.ext.dirs="/root/monitor_collect/lib"

在使用jdb 运行程序时,如果有以来jar 包,用户必须要使用 -classpath 参数,将相关的jar 全部填写进去,例如一个完整的启动命令

jdb -Dlog4j.configuration="file:/root/monitor_collect/log4j.properties"  \
-classpath /root/monitor_collect/lib/args4j-2.33.jar:/root/monitor_collect/lib/sequoiadb-driver-3.0.jar:/root/monitor_collect/lib/slf4j-api-1.7..jar:/root/monitor_collect/lib/log4j-1.2..jar:/root/monitor_collect/SdbMonitor.jar \
com.sequoiadb.monitor.MonitorAlarm

进入jdb后,会显示以下信息

Initializing jdb ...

然后用户就可以开始debug 了,先打一个断点。

打断点有两种方式

  1. 对某个类的方法打上断点
  2. 对某个类的行号打上断点

如果是对某个类的方法打断点,命令是

stop in com.sequoiadb.monitor.alarm.util.AlarmObject.analy_transaction

如果是对某个类的行号打断点,命令是

stop at com.sequoiadb.monitor.alarm.util.AlarmObject:

注意:类名一定要写全,包括package 名字也要写好。

运行的命令为:run

查看当前运行的堆栈信息为:where

执行下一步为:next

打印某个变量为:print

进入该行的函数为:step

从函数中跳出来为:step up

让程序从断点中继续执行为:cont

后面让我们再来看看,如果利用java 程序启动后,用户通过jdb 连接并且调试的。

用户在执行java 程序时,需要添加以下额外的参数,suspend=y 表示不加载主类,只有用户通过 jdb connect 后,再加载主类。

-Xdebug -Xrunjdwp:transport=dt_socket,address=,server=y,suspend=y

例如一个完整的命令:

java \
-Dlog4j.configuration="file:/root/monitor_collect/log4j.properties" \
-cp /root/monitor_collect/lib/args4j-2.33.jar:/root/monitor_collect/lib/sequoiadb-driver-3.0.jar:/root/monitor_collect/lib/slf4j-log4j12-1.7..jar:/root/monitor_collect/lib/slf4j-api-1.7..jar:/root/monitor_collect/lib/log4j-1.2..jar:/root/monitor_collect/SdbMonitor.jar \
-Xdebug -Xrunjdwp:transport=dt_socket,address=,server=y,suspend=y \
com.sequoiadb.monitor.MonitorAlarm

用户执行该命令后,窗口会挂起,用户可以在另外一个窗口中,继续操作(支持远程连接),如果需要远程连接,添加hostname 参数即可,如果hostname 参数不填写,默认为本地

jdb -connect com.sun.jdi.SocketAttach:port=,hostname=sdb1

用户通过 jdb connect 到远程的jave 程序后,操作方式和直接使用 jdb 启动程序的方式一致。

  • jstack

jstack 是jdk 又一个好用的debug 工具。它和jdb 不同,不是交互式地查看java 程序的相关调用和变量值,而是当用户的java 程序在运行过程中,突然出现 handle 的情况,而且该情况无法 100% 复现时,用户可以利用 jstack 工具将java 程序当前的堆栈信息全部打印出来。

这样用户可以通过堆栈信息分析程序到底是 handle 在什么地方。

jstack 打印java 程序当前的堆栈信息

jstack -l PID > java.jstack.out

参考博客:

http://blog.csdn.net/arkblue/article/details/39718947

https://www.ibm.com/developerworks/cn/java/joy-jdb/index.html

介绍jave 程序在启动 jdwp 时,各种参数的含义:http://chainhou.iteye.com/blog/1837059

java 定位问题方法 (jdb 和 jstack)的更多相关文章

  1. Java:方法的参数是传值还是传引用

    Java中方法的参数总是采用传值的方式. 下列方法欲实现对象的交换,但实际上是不能实现的. public void swap(simpleClass a,simpleClass b){ simpleC ...

  2. Java之方法重载篇(我重载了,你要如何来调用我。。)

      一.课前引言 请看一下代码,你发现什么特殊之处了吗? public class MethodOverload { public static void main(String[] args) { ...

  3. effective java —— 终结方法守卫者

    目录: effective java —— 终结方法守卫者 effective java 第2章:创建和销毁对象.第7条 : 避免使用终结方法.最后的“终结方法守卫者 (finalizer guard ...

  4. Java parseInt()方法

    1.Java parseInt()方法 使用此方法得到的原始数据类型的一个特定的字符串. parseXxx()是一个静态方法,可以有一个参数或两个. java parseInt() 语法:   sta ...

  5. 几种任务调度的 Java 实现方法与比较

    综观目前的 Web 应用,多数应用都具备任务调度的功能.本文由浅入深介绍了几种任务调度的 Java 实现方法,包括 Timer,Scheduler, Quartz 以及 JCron Tab,并对其优缺 ...

  6. JNI系列——C文件中的方法调用Java中方法

    1.创建xxx.jni包并在该包下实现一些Java的方法,和要调用的本地方法 2.实现MainActivity中的按钮点击事件-即点击按钮调用本地的方法 3.在C文件中的方法中回调Java的方法 3. ...

  7. java中方法参数的一些总结(1)

    1.问题说明        在C++中,函数调用时有传值调用和传址调用两种方式,但在Java中只有传值调用一种方式.Java中的方法参数为那几种基本数据类型的情况跟C++中一样,传入的只是变量的拷贝. ...

  8. 新手容易混乱的String+和StringBuffer,以及Java的方法参数传递方式。

    之前在交流群里和猿友们讨论string+和stringbuffer哪个速度快以及Java的方法参数传递的问题,引起了群里猿友的小讨论.最终LZ得出的结果是string+没有stringbuffer快, ...

  9. JAVA本地方法详解,什么是JAVA本地方法?

    一. 什么是Native Method   简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非j ...

随机推荐

  1. Selenium-鼠标操作

    有些特殊的系统可能需要模拟键盘或者鼠标的操作才可以 鼠标的操作不仅仅是click()单击操作,还有很多包含在ActionChains类中 context_click(elem) 右击鼠标点击元素ele ...

  2. HihoCoder1665方块游戏([Offer收割]编程练习赛40)(线段树)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho在玩一款类似俄罗斯方块的游戏.与原版俄罗斯方块不同的是,落下方块都是长度不一的横向长条,并且不能移动也不能变成竖直方 ...

  3. ACM学习历程—HDU 5025 Saving Tang Monk(广州赛区网赛)(bfs)

    Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Classi ...

  4. bzoj 2733 永无乡 线段树

    题目: 支持两种操作: 合并两点所在的联通块 查询某点所在联通块内权值第k小. 题解 平衡树启发式合并随便搞一搞就好了. 我写了一个线段树合并 #include <cstdio> #inc ...

  5. redis源码笔记 - redis-cli.c

    这份代码是redis的client接口,其和server端的交互使用了deps目录下的hiredis c库,同时,在这部分代码中,应用了linenoise库完成类似history命令查询.自动补全等终 ...

  6. 洛谷【P1177】【模板】基数排序

    题目传送门:https://www.luogu.org/problemnew/show/P1177 我对计数排序的理解:https://www.cnblogs.com/AKMer/p/9649032. ...

  7. Poj1050_To the Max(二维数组最大字段和)

    一.Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is an ...

  8. Ruby 局部变量做block参数

    Ruby中使用yield语句调用block时可以带有参数,参数值见传送个相关联的block.如果传给block的参数是已经存在的局部变量,那么这些变量即为block的参数,他们的值可能会因block的 ...

  9. [.net]手机APP与IIS服务器联调配置

    前端时间写过一段时间接口,在后期的时候,出现了一些无法通过查看日志来找出问题所在的bug.于是,将手机APP连接到IIS服务器上进行调试,下面是配置的具体步骤 1. 配置IIS  添加网站,将物理路径 ...

  10. AxInterop.ShockwaveFlashObjects.dll 问题

    在实际项目中引用此dll加载项目启动动画(swf),但在64位上此dll并不支持,解决办法有待商讨,个人在项目中,把加载动画的部分给注释掉了,不给项目中签入,他们用的都是32位系统,我的是64位的.请 ...