gpt4 book ai didi

java - Java 中 Heisenbugs 的可能和不太可能的原因?

转载 作者:搜寻专家 更新时间:2023-10-31 19:44:45 26 4
gpt4 key购买 nike

我有一个 Heisenbug 的经典示例,它是由我以前从未见过的条件触发的。我的遗留应用程序(大约 100K sloc 的旧代码)在特定实例中无法正常工作,仅仅启用 JPDA 远程调试足以改变行为,导致应用程序正常工作:除了添加“-Xdebug -Xnoagent -Xrunjdwp:什么都不做: transport=dt_socket,server=y,suspend=n,address=6666"到 vm 的命令行隐藏了错误(有或没有实际连接)。鉴于我有一个完全可重复的测试用例,我不喜欢用代码更改来扰乱它,以防它重新隐藏起来。当然,这仅发生在生产环境中。

通常,我会立即假设一个线程问题,但是 a) 行为是 100% 失败与 100% 工作,并且 b) 在有问题的代码路径中没有明确使用线程。我们的团队当时正试图列出导致这种行为的其他原因,所以我认为 Stack Overflow 的集体思维或许可以添加更多内容。

Java 中的 Heisenbug:

  • 线程:同步不良、竞争条件、隐式排序假设。
  • 显式调试/记录代码:更改代码路径会导致/预防问题。不太常见的是,日志级别的变化会导致时间变化(再次线程化)和 I/O 资源使用的差异。
  • native 代码库可能会拖入非 java Heisenbug 问题。
  • 期望终结器以可预测的方式运行。
  • 对弱引用的不当假设。
  • 假设固定大小的缓存永远不会填满。
  • 期望哈希码的唯一性。
  • 假设 == 适用于字符串(或不适用于某些情况下可能会被保留的字符串)。
  • VM 错误(不,永远不会 发生;)。
  • 测试方法错误。特别是当存在依赖于测试成功的隐藏变量时。 (这看起来是我们的实际问题。一次测试成功导致客户运行下一次测试,由于策略问题而失败。失败导致根据策略以 Debug模式运行,结果成功。叹气)

还有其他值得探索的案例吗?

编辑:

  • 是的,JPDA 启用代码使用旧语法。我没有测试过使用现代语法是否也会改变行为。
  • 这台特定机器使用 1.8.0_45-b14 作为 JRE 和 HotSpot 64 位服务器虚拟机(内部版本 25.45-b02)
  • 虽然问题是一般性的,但煽动问题是真实的和当前的。由于问题出现在已部署的系统中,我在想要让它以 -Xdebug 运行作为解决方法以使其保持运行和想要追踪潜在的错误并消除它之间左右为难。
  • 有问题的故障程序是多步骤数据处理管道的一部分 - 细节应该无关紧要,但最好将其理解为一个独立的应用程序,它从数据库中获取一些信息,然后使用它来修改一些文件.系统崩溃的部分似乎是来自数据库的信息没有被正确解释——任何来自损坏的对象 ORM 或缓存​​的信息。当它“损坏”时,确定它是否有工作要做的应用程序逻辑(基于数据库的内容)对所有迭代(数千次迭代,包括程序的多次调用)做出了错误的选择。当它“工作”时(唯一的区别是 vm 是否使用 -Xdebug 运行),应用程序为所有迭代做出正确的选择。在这个配置中是完全一致的。针对不同数据库运行的相同代码不会失败。有一些证据(在我参与这段代码之前)表明,过去曾出现过类似的行为,在看似很小的代码更改后神秘地开始工作……参见“Heisenbug”

最佳答案

-Xdebug 似乎是一个改变行为的开关。 What are Java command line options to set to allow JVM to be remotely debugged?声称添加它会使您从 JIT 转变为所有解释。其他 oracle java 文档 ( for jrocket admittedly ) 似乎表明它由于某些未指明的原因而变慢并且不适合已部署的系统。

我可以想象不同的 GC 方案可能会做出改变。

关于java - Java 中 Heisenbugs 的可能和不太可能的原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34679813/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com