【问题标题】:The crash happened outside the Java Virtual Machine in native code崩溃发生在 Java 虚拟机之外的本地代码中
【发布时间】:2012-08-20 11:58:22
【问题描述】:

我正在一台具有 32 个虚拟处理器和 32GB 内存的 Sun 服务器上进行网络爬取。

我打开了 1460 个线程来为我完成这项工作。我设置的运行时参数是-Xms2048-Xmx2048。我已经运行了两次代码,但它在不同的地方崩溃了。

> #
> # A fatal error has been detected by the Java Runtime Environment:
> #
> #  SIGSEGV (0xb) at pc=0xff390f38, pid=3053, tid=7640
> #
> # JRE version: 6.0_15-b03
> # Java VM: Java HotSpot(TM) Server VM (14.1-b02 mixed mode solaris-sparc )
> # Problematic frame:
> # C  [libc_psr.so.1+0xf38]  memset+0x78
> #
> # If you would like to submit a bug report, please visit:
> #   http://java.sun.com/webapps/bugreport/crash.jsp
> # The crash happened outside the Java Virtual Machine in native code.
> # See problematic frame for where to report the bug.
> #
> 

编辑:我将线程数减少到 40 个并在同一台服务器上运行它。在 RSS 的值超过 Swap 的值(两者都在 2150M 左右)时再次崩溃。换句话说,当内存超出限制时,它就崩溃了。然后我在我自己的带有 4G RAM 和双核处理器的 PC 上运行它。令我惊讶的是,到目前为止它一直做得很好。 PC 上的内存使用量保持在 1.5G 左右,距离限制有点远。它一直如此稳定地运行,以至于 PC 上似乎有一种机制可以防止内存达到其极限。相比之下,它在 Sun 服务器上似乎失控了。

编辑:自从我升级到最新的 64 位 Java 以来,它还没有崩溃过。

【问题讨论】:

  • 试过减少线程数吗? 10, 20, 30... 看看是否是缩放问题?如果您的每个线程都在连接网络,则意味着至少有 1460 个 TCP 传出连接。而且,如果他们不关闭主连接并检索其他资源(HTML -> JS、CSS、IMG),它们就会成倍增加!您只有 2^16 个可用端口 (65535)。事实上,其中很多已经被使用了。
  • 您使用的是JRE version: 6.0_15-b03。首先尝试升级到最新的 JRE。最新升级版本为34Things happened between 15 and 34...
  • 这是一个缩放问题。 memset 失败,因为系统无法分配空间来支持映射。 (除非这是一个 32 位应用程序,在这种情况下,当大小的低 32 位全为零时,可能会出现一个模糊的错误。)
  • 你有没有考虑过使用 NIO 而不是一千多个线程?仅堆栈内存开销就应该值得。另见:stackoverflow.com/questions/592303/asynchronous-io-in-java
  • 对于您的编辑,Sun JVM 实现似乎有些东西没有释放资源。但我想它只发生在某些情况下。否则它应该是一个大错误。我完全赞成非阻塞 API,使用与 CPU 内核一样多的线程,并使用回调接口来处理响应。然后,每个新事件(要获取的新 URL,要解析的新响应)都是您必须分配到工作队列的新任务...

标签: java multithreading jvm native-code jvm-crash


【解决方案1】:

您是否尝试将“M”附加到内存参数? (即 -Xms2048M)另外,我会尝试将 ms 设置为较小的值(即 1024M),以防 VM 无法为堆保留足够的空间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多