项目中的守护线程死掉,如何处理

xiaojimanman
博客专家认证
2013-12-25 11:01:44
程序抛出的异常信息如下:

Exception in thread "Lucene Merge Thread #10718" java.lang.OutOfMemoryError: class allocation, 64669416888 loaded, 4235051008 footprint JVM@check_alloc (src/jvm/model/classload/classalloc.c:118). 340 byte
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:971)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:965)
at java.lang.Thread.dispatchUncaughtException(Thread.java:1821)

Exception in thread "Index Commit Thread" java.lang.NoClassDefFoundError: java/lang/ThreadDeath
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:971)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:965)
at java.lang.Thread.dispatchUncaughtException(Thread.java:1821)

线程描述如下:线程的作用就是每隔一定的时间将内存中的数据写到磁盘上以保证程序使用磁盘在一定范围内,不会内存溢出。

代码如下:

private class IndexCommitThread extends Thread{
private boolean flag;
public IndexCommitThread(String name){
super(name);
}

public void run(){
flag = true;
while(flag) {
try {
indexWriter.commit();
System.out.println("commit");
TimeUnit.SECONDS.sleep(indexCommitSeconds);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}


问题如下:在运行过程中,就直接报上面的异常,导致内存中的数据无法写到磁盘上,导致程序运行出错。(程序已经正常运行了20天左右,今天第一次出现这个问题)

求指点,该为题该如何解决?
...全文
1630 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaojimanman 2014-01-08
  • 打赏
  • 举报
回复
页面上: http://docs.oracle.com/cd/E15289_01/doc.40/e15066/knownissues.htm#CJADHDEA 4.18 Out of Memory Error Occurs When Classblock Memory Runs Low 也许是因为这个原因,但是jrrt-4.0.1-1.6.0 这个版本并不支持上述的参数设置。也就只能静观其变了
xiaojimanman 2013-12-27
  • 打赏
  • 举报
回复
出现的原因找到了: 在你调节mergeFactor值的时候要注意,如果超过了JVM运行的最大内存的阈值,将会抛出java.lang.OutOfMemoryError异常 这个该如何解决?
xiaojimanman 2013-12-27
  • 打赏
  • 举报
回复
引用 6 楼 ygycomon 的回复:
引用 5 楼 xiaojimanman 的回复:
[quote=引用 2 楼 ygycomon 的回复:] 一个内存放不下就分开两步做
不是内存放不下,是将内存中的数据写到磁盘中的线程死掉了,今天才发现是 Exception in thread "Lucene Merge Thread #10718" java.lang.OutOfMemoryError 这个错误,好几台机器都没有问题,就其中的一台机器出现了这个问题,这个问题也不知道如何重现。
内存溢出就是内存放不下了啊,如果是自己的算法的话,就换个思路,分而治之;如果不是自己的算法,就调大一点堆内存吧,不知道你堆内存设置的值是多少,32位和64位上限也不一样[/quote]是lucene4.3.1这个版本,回写机制是架包里面固定的,现在估计问题很有可能是因为 “Expert: IndexWriter allows you to separately change the MergePolicy and the MergeScheduler. The MergePolicy is invoked whenever there are changes to the segments in the index. Its role is to select which merges to do, if any, and return a MergePolicy.MergeSpecification describing the merges. The default is LogByteSizeMergePolicy. Then, the MergeScheduler is invoked with the requested merges and it decides when and how to run the merges. The default is ConcurrentMergeScheduler.”这是lucene的说明文档,说默认的模式是:LogByteSizeMergePolicy,但是jar包里面的代码确不是这个,现在修改方法是在代码中添加如下代码: LogByteSizeMergePolicy mergePolicy = new LogByteSizeMergePolicy(); mergePolicy.setMergeFactor(Config.getMergeFactor()); indexWriterConfig.setMergePolicy(mergePolicy); 目前只有出问题的机器修改成这种模式,需要运行几天看下是否还会出现这个情况。
致知Fighting 2013-12-27
  • 打赏
  • 举报
回复
引用 5 楼 xiaojimanman 的回复:
引用 2 楼 ygycomon 的回复:
一个内存放不下就分开两步做
不是内存放不下,是将内存中的数据写到磁盘中的线程死掉了,今天才发现是 Exception in thread "Lucene Merge Thread #10718" java.lang.OutOfMemoryError 这个错误,好几台机器都没有问题,就其中的一台机器出现了这个问题,这个问题也不知道如何重现。
内存溢出就是内存放不下了啊,如果是自己的算法的话,就换个思路,分而治之;如果不是自己的算法,就调大一点堆内存吧,不知道你堆内存设置的值是多少,32位和64位上限也不一样
xiaojimanman 2013-12-27
  • 打赏
  • 举报
回复
引用 2 楼 ygycomon 的回复:
一个内存放不下就分开两步做
不是内存放不下,是将内存中的数据写到磁盘中的线程死掉了,今天才发现是 Exception in thread "Lucene Merge Thread #10718" java.lang.OutOfMemoryError 这个错误,好几台机器都没有问题,就其中的一台机器出现了这个问题,这个问题也不知道如何重现。
xiaojimanman 2013-12-27
  • 打赏
  • 举报
回复
引用 3 楼 huxiweng 的回复:
你加载了什么,用这么多内存,写文件结束要关闭流
这是是使用lucene过程中的一个守护线程,就是将内存中的索引回写到磁盘中
teemai 2013-12-27
  • 打赏
  • 举报
回复
你加载了什么,用这么多内存,写文件结束要关闭流
致知Fighting 2013-12-27
  • 打赏
  • 举报
回复
一个内存放不下就分开两步做

51,396

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧