对生产环境内存溢出的分析1

昨天下午,生产环境168服务器突然报内存溢出.临时抓了jvm快照.重启解决.
今天分析jvm快照.一眼就发现有对象貌似存在异常.DictSegment对象在JVM中有60W+个实例化的对象.
 
    凭经验,一般的JVM溢出都是有对象没有处理好.GC没有回收,导致在JVM里越来越多导致.所以首先排查调用这个类的方法.
    检查代码,发现只有一个类IndexCreateUtil使用到了DictSegment.方法本身的实现上没有问题.网上的demo方法都是这样使用的.
    实践出真知.自己写个测试类.
public class TestIndexCreateUtil2 {
@Test
public void testSplitBySegmenterStringBooleanBoolean() {
User user = new User();
testFenCi2();
try {
System.gc();
// 先不要停止,抓内存使用情况
Thread.sleep(1000000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
 
private void testFenCi2(){
String text = "让战士们过一个欢乐祥和的新春佳节。";
// 创建分词对象
StringReader reader = new StringReader(text);
Role role = new Role();
IKSegmenter ik = new IKSegmenter(reader, true);// 当为true时,分词器进行最大词长切分
Lexeme lexeme = null;
try {
while ((lexeme = ik.next()) != null) {
System.out.println(lexeme.getLexemeText());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
reader.close();
}
}
}
    在System.gc();行加断点.抓取JVM发现.执行到System.gc();时.特意加的role 对象还是存在的,但从Eclipse里没法查看了,这应该是还没有执行过GC导致的.另一个更重要的是.DictSegment类有60W+个实例化的对象.
    再次问度娘,调用方法都是对的,大概看了一下,感觉跟IKAnalyzer本身的分词算法可能有关.
    换一个思路.使用IKAnalyzer的作用就是加一些tag.没有使用其他比较高深的东西.那换一个分词软件行不行?
    找到度娘比较推荐的ansj测试.功能可以实现.也没有产生几十万个相同的类对象.再看内存使用.悲剧了.一句分词,内存直接从10M不到飙升到接近100M.而IKAnalyzer内存变动在10M以内的.
    
     综合考虑.还是不换IKAnalyzer了.在此标记一下.抓取到的JVM快照中如果有60W+个DictSegment对象.是正常的(但确实有点奇葩:).
    JVM溢出的原因待继续查找.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值