【问题标题】:HBase java.lang.OutOfMemoryErrorHBase java.lang.OutOfMemoryError
【发布时间】:2011-01-24 19:52:31
【问题描述】:

我在使用 Hbase 时遇到以下问题。

我有一个脚本,它启动 HBase shell 并将许多行插入到具有单列的表中。我尝试插入 10,000 行,但在大约 1,700 行之后,我得到了可怕的“java.lang.OutOfMemoryError:无法创建新的本机线程”错误。我尝试将 Java 堆大小从默认的 1000mb 更改为 1800mb,但这不允许我插入超过 1700 左右的行。

但是,我注意到我可以插入 1000 行、退出 shell、重新启动 shell、在同一个表中再插入 1000 行、再次退出等等。我对 JVM 的了解还不够,无法弄清楚为什么它允许我在多个会话中执行此操作,但不允许我在同一个会话中批量插入。

有人可以向我解释一下这里发生了什么,我可以做些什么吗?

编辑:

我现在使用的是 64 位机器,red hat linux 5,Java 1.6。我给 HBase 的堆大小为 20gb(我总共有大约 32 gigs 内存)。 对于堆栈大小,我给 8mb。我相信 64 位的默认值是 2mb;使用 2mb 时我遇到了同样的错误,将其增加到 8mb 根本没有帮助(无论堆栈大小如何,我都只能插入相同数量的行,~1700)。

我已经读到减小堆大小可以使这个错误消失,但这也没有帮助。下面是我正在设置的 jvm 选项(除了堆栈大小,一切都是默认的)。

HBASE_OPTS="$HBASE_OPTS -ea -Xss8M -XX:+HeapDumpOnOutOfMemoryError -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode"

【问题讨论】:

  • 你能分享你设置的 JVM 参数吗?

标签: java jvm hadoop hbase


【解决方案1】:

我昨天遇到了这个错误。在我的情况下发生的事情是,我创建了很多 HTable 实例,当我在记录中使用 put 时创建了太多线程。 (我正在使用映射器并在 map 函数中创建它)

我会检查是否大量创建了与 HBase 的连接(在循环或 map 函数内。如果发生这种情况,则将其移动以实例化更少的 HBase 连接(我使用了 HTable ) 可以解决问题。 它解决了我的问题。

HTH

【讨论】:

  • 当我使用 Java 客户端连接到 HBase 以及将脚本传递给 HBase shell 时,就会发生这种情况。 shell 脚本只是一个放置命令的列表,一个接一个。在这两种情况下(使用 Java 客户端和使用 shell 脚本),我都会在相同的行数后得到错误。
  • 为了继续我之前的评论,我在 Java 客户端中进行了此更改,它确实有效...这次我能够插入更多的行。但是,我很困惑为什么我仍然无法通过 shell 插入超过 1600 行,或者是什么导致了这个错误。你有什么想法吗?
  • 在 JAVA 中,这是一个为 NVM 中的每个线程分配内存并用完空间来分配另一个线程的问题。我不擅长 JVM 的内部结构等,所以我可能会掩盖一些细节。对于外壳,我的想法较少-但它可能正在做相同类型的事情,并尝试为每个 put 创建一个新线程? 耸耸肩我没有玩过它,所以我不确定。
【解决方案2】:

我在使用HTablePool 实例来获取我的HTableInterface 实例时遇到了这个错误,但是在使用之后我忘记在其上调用close() 方法。

【讨论】:

    【解决方案3】:

    我也遇到了同样的问题,正如上面 kosii 所解释的,根本原因是没有关闭我在使用后从 HTablePool 获得的 HTableInterface 实例。

    HTableInterface table = tablePool.getTable(tableName);
    // Do the work
    ....
    ....
    table.close()
    

    【讨论】:

      猜你喜欢
      • 2017-05-23
      • 2013-02-05
      • 1970-01-01
      • 2016-11-12
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多