这些JDK问题也已在1.6.9_29(不仅是1.7.0u1)中修复。ReadVInt不再崩溃。因此,您的崩溃与任何“著名的java6 /
7错误”都没有关系(vint错误根本不会使JVM崩溃,它只是通过返回错误的值来破坏索引-并且该问题从Lucene 3.1开始就已得到修复)。
但是还有另一种可能使JVM崩溃的机会:您在64位平台(Linux)上,因此默认目录实现是MMapDirectory。Lucene使用黑客可以从虚拟地址空间取消映射文件的映射。JVM本身不允许这样做,但是使取消映射依赖于垃圾收集器,这对于Lucene来说是个问题。默认情况下,MMapDirectory在关闭IndexInputs后取消映射文件。MMapDirectory根本不同步,因此,当另一个线程在取消映射后尝试访问IndexInput时,它将访问未映射的地址,并将访问SIGSEGV。
如果您的代码正确,则不会发生这种情况,但是看起来您正在使用已关闭的IndexReader / IndexWriter访问索引。在Lucene
3.5(即将推出)之前,缺少IndexReader中的检查将可能使一个已经关闭的IndexReader及其所有关闭(且未映射)的IndexInputs尝试访问索引数据和段错误。
在3.5中,我们添加了其他安全检查来防止这种非法访问,但是不是100%(因为缺少同步)。我将检查代码,并检查没有任何东西可以访问封闭索引。
一个简单的检查(是否为您的问题)是使用NIOFSDirectory(在Linux上速度较慢)而不是MMapDirectory。如果它没有崩溃并且可能引发AlreadyClosedExceptions,则该错误正在访问已关闭的索引。



