【问题标题】:JVM crashes on Lucene DataInput.readVIntJVM 在 Lucene DataInput.readVInt 上崩溃
【发布时间】:2011-11-22 09:50:52
【问题描述】:

在使用 Lucene 索引文档时,我的 JVM (1.6.0_29) 在密集使用时不断崩溃。 我明白了:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00002b6b196d767c, pid=26417, tid=1183217984
#
# JRE version: 6.0_29-b11
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.4-b02 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# J  org.apache.lucene.store.DataInput.readVInt()I
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

环境:

JDK:1.6u29(与 1.6_02 相同的问题) Lucene 版本 3.4.0

vm_info:用于 linux-amd64 JRE (1.6.0_29-b11) 的 Java HotSpot(TM) 64 位服务器 VM (20.4-b02),由“java_re”和 gcc 3.2 于 2011 年 10 月 3 日 01:19:20 构建.2 (SuSE Linux)

操作系统:CentOS 5.0 版(最终版)

jvm_args: -Dcatalina.home=/var/local/tomcat-8081 -Dcatalina.base=/var/local/tomcat-8081 -Djava.io.tmpdir=/var/tmp -Dfile.encoding=UTF-8 -Xmx1024M -XX:MaxPermSize=96m

这似乎是 jdk 1.7 中修复的 jdk 问题,但引入了其他问题。 https://issues.apache.org/jira/browse/LUCENE-3335 “Java 7 包含自 1.6.0_21 以来对 readVInt 问题的修复(大约,LUCENE-2975)”

那么,如何使用 JDK 1.6 解决这个问题? 我应该升级到 jdk 1.7 吗?

【问题讨论】:

    标签: java lucene jdk1.6 segmentation-fault java-7


    【解决方案1】:

    这些 JDK 问题也在 1.6.9_29(不仅仅是 1.7.0u1)中得到修复。 ReadVInt 不能再崩溃。因此,您的崩溃与任何“著名的 java6/7 错误”都无关(vint 错误根本不会使您的 JVM 崩溃,它只会通过返回错误值来破坏您的索引 - 自 Lucene 3.1 以来这个问题肯定已修复)。

    但是还有另一个可能导致 JVM 崩溃:您在 64 位平台 (Linux) 上,因此默认目录实现是 MMapDirectory。 Lucene 使用 hack 能够从虚拟地址空间取消映射文件。 JVM 本身不允许这样做,但会使取消映射依赖于垃圾收集器,这对 Lucene 来说是个问题。默认情况下,MMapDirectory 在关闭 IndexInputs 后取消映射文件。 MMapDirectory 根本不同步,因此当另一个线程在取消映射后尝试访问 IndexInput 时,它将访问一个未映射的地址并会 SIGSEGV。

    如果您的代码正确,这不会发生,但看起来您正在使用已经关闭的 IndexReader/IndexWriter 来访问索引。在 Lucene 3.5(即将推出)之前,IndexReader 中缺少检查将导致已经关闭的 IndexReader 及其所有已关闭(且未映射)的 IndexInputs 尝试访问索引数据和段错误。

    在 3.5 中,我们添加了额外的安全检查来防止这种非法访问,但它不是 100%(因为缺少同步)。我会查看代码并检查是否没有任何内容可以访问已关闭的索引。

    检查这是否是您的问题的简单检查是使用 NIOFSDirectory(在 Linux 上较慢)而不是 MMapDirectory。如果它没有崩溃并且可能抛出 AlreadyClosedExceptions,则该错误正在访问已关闭的索引。

    【讨论】:

    • 谢谢,我能够解决重写我的 SearchManager 类的问题。
    【解决方案2】:

    根据this article,以下情况也可能在 Java 6 中导致:

    请注意:Java 6 用户也会受到影响,如果他们使用其中之一 JVM 选项,默认情况下未启用: -XX:+OptimizeStringConcat 或 -XX:+AggressiveOpts

    你正在使用它们中的任何一个吗?

    【讨论】:

    • 不,我不是。这就是我正在使用的:jvm_args: -Dcatalina.home=/var/local/tomcat-8081 -Dcatalina.base=/var/local/tomcat-8081 -Djava.io.tmpdir=/var/tmp -Dfile。编码=UTF-8 -Xmx1024M -XX:MaxPermSize=96m
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2014-10-13
    • 2016-10-11
    相关资源
    最近更新 更多