java - Oracle T4CPreparedStatement 内存泄漏?

标签 java memory-leaks oracle10g performance

我将在接下来的几行中介绍有关该应用程序的一些背景信息:

XYZ 是一个数据屏蔽工作台 eclipse RCP 应用程序:您给它一个源表列和一个目标表列,它将应用转换(加密/改组/等)并复制该行从源表到目标表的数据。现在,当我一次屏蔽 n 个表时,此应用程序将启动 n 个线程。

问题是:

我在首次推出上述应用时遇到了生产问题。不幸的是,我没有任何日志可以到达根目录。但是,我尝试在测试区域运行此应用程序并进行压力测试。

当我收集 .hprof 文件并通过分析器 (yourKit) 运行它们时,我注意到 oracle.jdbc.driver.T4CPreparedStatement 的对象保留了堆。分析还告诉我,我的一个类持有对这个 preparedstatement 对象的引用,因此,n 个线程有 n 个这样的对象。 T4CPreparedStatement 似乎有字符数组:lastBoundChars 和 bindChars,每个大小都是 char[300000]。

所以,我研究了一下(谷歌!),获得了 ojdbc6.jar 并尝试反编译 T4CPreparedStatement。我看到 T4CPreparedStatement 扩展了 OraclePreparedStatement,它动态管理 lastBoundChars 和 bindChars 的数组大小。

所以,我的问题是:

  1. 你有没有遇到过这样的问题 这个?
  2. 你知道的意义吗 lastBoundChars/bindChars?
  3. 我是分析新手,你也是 认为我做的不正确? (我 还通过 MAT 运行了 hprofs - 这是主要确定的 问题 - 所以,我真的不认为我 可能是错的?)

我在网上找到了类似的东西: http://forums.oracle.com/forums/thread.jspa?messageID=2860681

感谢您的建议/忠告。

最佳答案

我遇到了同样的问题。尽管 Affe 的泄漏可能是问题所在,但这不是我的问题,经过一番挖掘后我找到了不同的答案:

Oracle JDBC 驱动程序维护缓冲区,将数据读入缓冲区以优化性能。缓冲区大小是根据可能的最大行大小(因此 VARCHAR(2000) 将分配类似 2000 个 char 的内容)乘以 JDBC 提取大小计算得出的。这允许驱动程序直接将数据读入缓冲区,而不是按需分配(显然)速度较慢。

每个连接中的每个准备好的语句都维护一个这种缓冲区。如果您正在使用带有语句缓存的大型连接池(或者您手动缓存 PreparedStatement 对象,或者泄漏它们...),那么您会迅速耗尽大量堆空间。我的情况是 1.6GB!

这一切都由 Oracle 自己在 PDF here 中解释。

我的体验是基于11.2.0.3驱动。

关于java - Oracle T4CPreparedStatement 内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2876895/

相关文章:

java - 具有多个 Activity 的 Android 共享首选项

java - 这种形式的内存管理在 Java 中是否有意义?

java - C 内存泄漏与 packetsender 套接字

spring - Java 包 org.apache.poi.hssf.usermodel.* 的 Jar 实用程序

oracle - to_date 函数与 sysdate

.net - oracle sql Developer中的J2SE SDK配置

Java - 如果单词以用户输入的定界符结尾,则执行 x

java - 为什么当我使用 BigDecimal 时我的操作不起作用?

java - 如何动态地将英语 "abc123 "数字转换为阿拉伯语 "ابث١٢٣ "android

objective-c - 无法弄清楚这个泄漏