本文介绍了我用于调试各种代码库的技术,例如:
- 具有高并发性的CodeBase。
- 代码库包含许多专有(不受支持的)库。
- 代码库中包含大量弃用/不需要的代码。
- CodeBase 存在内存泄漏。
- 每个 JVM 都可以与其他 JVM 通信的代码库。
让我们逐一看一下。
具有高并发性的CodeBase。
为了处理一个请求,JVM 可能会使用许多线程,例如:
Req -> tomcatThread-1 -> executorThread-2 -> BizThread-3->…`
假设我们发现异常出现在 BizThread-3 中。现在作为调试器,我们想要了解请求流程。但堆栈跟踪无法提供完整的请求流程(例如,executorThread-2 中发生了什么以及 tomcatThread-1 中发生了什么等等)。
技术 1.1:编写 自定义 java-agent ,用于有效地添加 log.debug()
到某些 java 包的每个方法的开头和结尾。这将让我们了解所有被调用的内容。
技术 1.2:在某些框架中,如果支持,使用 AOP 代理所有方法并有效地添加 log.debug()
.
代码库包含许多专有(不受支持的)库。
有时,我们会发现这样的情况:经过数小时的调试后,我们发现 xyz-gov-secret 库行为异常,并且该库现在不受支持。
技巧 2.1:卷起袖子,安装 eclipse-decompiler 并深入研究代码库。
代码库中包含大量弃用/不需要的代码。
这是一个典型的问题:我们有时会发现自己的方法有 500 多行,其中包含大量已弃用的 if-else。现在,我们如何确定特定调用的代码流程是什么,将使用哪些 if-else,哪些是死代码?
工具 的 jacoco agent 。它在运行时收集执行细节,并可以在 eclipse 中对代码进行颜色编码。基本上,它是相同的工具,通常用于通过 JUnit Test 分析代码覆盖率。
CodeBase 存在内存泄漏。
每个开发人员都会有这样的一天,在本地系统中一切顺利,但在生产中却出现内存不足 :(
技术 4.1: JVM provides techniques to capture heap dumps in case of outOfMemory.启动 JVM 时添加以下内容作为参数 -XX:+HeapDumpOnOutOfMemoryError . 这将捕获堆转储并将其放入文件中,该文件可用于分析消耗内存的内容。
获取正在运行的 JVM 的堆转储/线程转储 jProfiler / Jvisiualvm .
每个 JVM 都可以与其他 JVM 通信的代码库。
当你陷入意大利面条式分布式环境时,追踪请求流会变得很困难。
技术 5.1:您可以使用 Wireshark 。Wireshark 捕获网络数据并将其显示在漂亮的 UI 中。然后,您可以查看流经系统的 HTTP 请求/响应
荣誉奖
技巧 6.1:在单线程环境中,故意插入 try catch
以便快速了解堆栈跟踪。
try {
throw new RuntimeException();
} catch(Exception e){
e.printStackTrace();
}
技巧6.2:使用eclipse断点或使用条件断点。
技术 6.3: https://en.wikipedia.org/wiki/Rubber_duck_debugging
发表评论 取消回复