【发布时间】:2021-02-01 17:48:13
【问题描述】:
TL;DR - 用户有错误(ORA-01438:值大于指定精度允许此列)。我无法在本地重新创建它,因为当我的机器运行多线程应用程序时,一次只有十个线程中的一个按顺序运行。此外,运行它通常会导致我的机器用完堆,即使为堆分配了 8GB,然后我碰巧遇到了 NullPointerException 而不是用户的问题。
我正在尝试调试多年前由不再存在的人编写的多线程遗留 Java 应用程序 (JDK 1.6)。它正在尝试将一些数据插入 Oracle DB。该应用程序通常在 Weblogic 11G 服务器上运行,大约需要 5 分钟才能完成运行计算。但是,在本地调试时,线程不会同时工作,它们会在我的本地机器上轮流工作。这使得运行时间从前面提到的 5 分钟变为约 1 小时,并且仍然设法用完堆(我给了它 8GB)或者如果幸运的话抛出 NullPointerException,但这不是业务用户的错误。本来想把它剪下来只用一个线程,反正都是轮流使用的,但是摸了一周之后,业务影响就变得真实了,我不能一直用锤子敲它。
鉴于我没有提供代码和代码,这可能是一个长镜头,但有人遇到过类似问题吗?特别是为什么线程会轮流。
编辑:用户的错误是违反约束的,所以我认为它正在修改输入的数据并做一些事情,比如增加额外的精度。
问题:应用程序的 10 个线程是按顺序工作而不是同时工作,并且代码可能包含内存泄漏,导致应用程序崩溃并且没有遇到业务用户遇到的约束违反异常的同一代码。
编辑 2:我怀疑线程权衡,而不是同时运行,可能会导致它们不在我的本地机器上运行垃圾收集?不过,如果我很幸运没有用完堆,它仍然不能解释我收到与业务用户不同的错误的问题。
【问题讨论】:
-
我不是数据库人员,所以不太可能回答,但也许您可以多说一下“在...服务器上”和“本地”之间的区别。特别是在这两种情况下,应用程序如何连接到数据库?
-
另外,除了连接上可能存在的差异之外,“尝试调试”与应用程序正常运行的方式有何不同?
-
您使用的是什么 JVM?它们在服务器和您的机器上是否相同?将哪些参数传递给 JVM?他们是一样的吗?这个应用程序做了多少日志记录?像这样一个实现良好的应用程序将能够将日志记录级别设置为它会告诉您它在做什么的程度。 (致所有阅读本文的经理和技术主管:本周的业务影响是因为您没有在关键业务应用程序中强制实施正确的日志记录。在应用程序的生命周期中花费了多少时间来修复这样的事情?)
-
如果代码不断地创建对象的新实例并且它们永远不会超出范围或没有被取消引用,那么是的,你会用完堆,但这表现为 OutOfMemoryError 而不是 NullPointerException。如果您看到 NullPointerException,那是因为您有一个为 null 的引用,这并不意味着您的内存已用完。这些是非常不同且不相关的问题。
-
最好的办法是在像 yourkit java profiler(我个人最喜欢的)这样的分析器下运行代码。这将向您显示线程争用和内存使用情况。
标签: java multithreading concurrency java-6