java - org.postgresql.jdbc.PgResultSet 实例和 io.vertx.core.impl.VertxThread 内存泄漏

标签 java memory-leaks out-of-memory vert.x jooq

enter image description here我在我的应用程序中使用 vert.x 和 jooq。我有一种从数据库获取数据的方法。该方法被连续调用,但一个接一个(在其他方法成功的情况下)。一段时间后,我遇到了堆内存不足的问题。我使用 Eclipse 内存分析器检查了堆转储,它显示一个对象存在内存泄漏,即 org.postgresql.jdbc.PgResultSet。它显示了两个问题。第二个是线程 io.vertx.core.impl.VertxThread @ 0x680c5eb80 保留总大小为 2,246,312,920 (38.58%) 字节的局部变量。但我根据给出的提示,两者都是相关的。

以下是eclipse工具提供的stacktrace

[![at org.postgresql.core.UTF8Encoding.decode(\[BII)Ljava/lang/String; (UTF8Encoding.java:156)
  at org.postgresql.core.Encoding.decode(\[B)Ljava/lang/String; (Encoding.java:215)
  at org.postgresql.jdbc.PgResultSet.getString(I)Ljava/lang/String; (PgResultSet.java:1926)
  at com.zaxxer.hikari.pool.HikariProxyResultSet.getString(I)Ljava/lang/String; (Unknown Source)
  at org.jooq.tools.jdbc.DefaultResultSet.getString(I)Ljava/lang/String; (DefaultResultSet.java:114)
  at org.jooq.impl.CursorImpl$CursorResultSet.getString(I)Ljava/lang/String; (CursorImpl.java:938)
  at org.jooq.impl.DefaultBinding$DefaultStringBinding.get0(Lorg/jooq/BindingGetResultSetContext;)Ljava/lang/String; (DefaultBinding.java:3334)
  at org.jooq.impl.DefaultBinding$DefaultStringBinding.get0(Lorg/jooq/BindingGetResultSetContext;)Ljava/lang/Object; (DefaultBinding.java:3270)
  at org.jooq.impl.DefaultBinding$AbstractBinding.get(Lorg/jooq/BindingGetResultSetContext;)V (DefaultBinding.java:774)
  at org.jooq.impl.CursorImpl$CursorIterator$CursorRecordInitialiser.setValue(Lorg/jooq/impl/AbstractRecord;Lorg/jooq/Field;I)V (CursorImpl.java:1771)
  at org.jooq.impl.CursorImpl$CursorIterator$CursorRecordInitialiser.operate(Lorg/jooq/impl/AbstractRecord;)Lorg/jooq/impl/AbstractRecord; (CursorImpl.java:1740)
  at org.jooq.impl.CursorImpl$CursorIterator$CursorRecordInitialiser.operate(Lorg/jooq/Record;)Lorg/jooq/Record; (CursorImpl.java:1705)
  at org.jooq.impl.RecordDelegate.operate(Lorg/jooq/impl/RecordOperation;)Lorg/jooq/Record; (RecordDelegate.java:125)
  at org.jooq.impl.CursorImpl$CursorIterator.fetchNext()Lorg/jooq/Record; (CursorImpl.java:1669)
  at org.jooq.impl.CursorImpl$CursorIterator.hasNext()Z (CursorImpl.java:1636)
  at org.jooq.impl.CursorImpl.fetchNext(I)Lorg/jooq/Result; (CursorImpl.java:408)
  at org.jooq.impl.CursorImpl.fetch(I)Lorg/jooq/Result; (CursorImpl.java:394)
  at org.jooq.impl.CursorImpl.fetch()Lorg/jooq/Result; (CursorImpl.java:301)
  at org.jooq.impl.AbstractResultQuery.execute(Lorg/jooq/ExecuteContext;Lorg/jooq/ExecuteListener;)I (AbstractResultQuery.java:297)
  at org.jooq.impl.AbstractQuery.execute()I (AbstractQuery.java:350)
  at org.jooq.impl.AbstractResultQuery.fetch()Lorg/jooq/Result; (AbstractResultQuery.java:323)
  at org.jooq.impl.AbstractResultQuery.fetchInto(Ljava/lang/Class;)Ljava/util/List; (AbstractResultQuery.java:1440)
  at org.jooq.impl.SelectImpl.fetchInto(Ljava/lang/Class;)Ljava/util/List; (SelectImpl.java:3741)
  at com.module.BuildConfigCacheManagerImpl.lambda$getAllConfigurations$3(Ljava/util/List;Lorg/jooq/DSLContext;)Ljava/util/List; (BuildConfigCacheManagerImpl.java:99)
  at com.module.BuildConfigCacheManagerImpl$$Lambda$501.apply(Ljava/lang/Object;)Ljava/lang/Object; (Unknown Source)
  at io.github.jklingsporn.vertx.jooq.classic.jdbc.JDBCClassicGenericQueryExecutor.lambda$executeAny$0(Ljava/util/function/Function;Lio/vertx/core/Future;)V (JDBCClassicGenericQueryExecutor.java:30)
  at io.github.jklingsporn.vertx.jooq.classic.jdbc.JDBCClassicGenericQueryExecutor$$Lambda$486.handle(Ljava/lang/Object;)V (Unknown Source)
  at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$2(Lio/vertx/core/spi/metrics/PoolMetrics;Ljava/lang/Object;Lio/vertx/core/Handler;Lio/vertx/core/Handler;)V (ContextImpl.java:272)
  at io.vertx.core.impl.ContextImpl$$Lambda$439.run()V (Unknown Source)
  at io.vertx.core.impl.TaskQueue.run()V (TaskQueue.java:76)
  at io.vertx.core.impl.TaskQueue$$Lambda$90.run()V (Unknown Source)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V (ThreadPoolExecutor.java:1128)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run()V (ThreadPoolExecutor.java:628)
  at io.netty.util.concurrent.FastThreadLocalRunnable.run()V (FastThreadLocalRunnable.java:30)
  at java.lang.Thread.run()V (Thread.java:834)][1]][1]

任何人都可以帮我这里出了什么问题吗?

最佳答案

涉及 JDBC 结果集的“内存泄漏”可能是由于以下三个原因之一造成的:

  1. 大量数据被提取到客户端。这不会是泄漏,而是内存使用效率低下。可以通过 ResultQuery.fetchSize() 指定 JDBC 获取大小来解决这个问题
  2. 您正在将一个巨大的对象提取到客户端中。该异常由 getString() 调用触发。也许该特定字符串太大而无法提取到内存中。您可以使用 data type binding在 jOOQ 之上实现大对象流逻辑。
  3. 连接池生成的代理连接无法正确关闭相关资源,例如结果集。在这种情况下,连接池中可能存在配置错误或错误。

关于java - org.postgresql.jdbc.PgResultSet 实例和 io.vertx.core.impl.VertxThread 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57180465/

相关文章:

java - 将实际输入值存储到数组中以便与另一个数组进行比较

Java:有没有一种方法可以在取消部署我的应用程序之前删除所有 ThreadLocal?

Null 但既不是 Empty 也不是 Blank 的 Java 注释

c# - 当你做错一切时追踪内存泄漏的策略

JDBC批量插入OutOfMemoryError

java - 在plugin.yml中找不到主类

ios - 无法修复 Objective-C ARC 多线程 iOS 应用程序中的特定内存泄漏

Java/Groovy - GroovyClassLoader 中的内存泄漏

java - 线程 OutOfMemoryError,强制关闭

java - 堆栈帧大小是否有上限