博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一次MongoDB分页查询导致的OOM问题
阅读量:5836 次
发布时间:2019-06-18

本文共 4850 字,大约阅读时间需要 16 分钟。

hot3.png

OOM描述信息:

2018-09-18 14:46:54.338 [http-nio-8099-exec-8] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [/party-data-center] threw exception [Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: GC overhead limit exceeded] with root causejava.lang.OutOfMemoryError: GC overhead limit exceeded	at org.bson.io.ByteBufferBsonInput.readString(ByteBufferBsonInput.java:154)	at org.bson.io.ByteBufferBsonInput.readString(ByteBufferBsonInput.java:126)	at org.bson.BsonBinaryReader.doReadString(BsonBinaryReader.java:245)	at org.bson.AbstractBsonReader.readString(AbstractBsonReader.java:461)	at org.bson.codecs.BsonStringCodec.decode(BsonStringCodec.java:31)	at org.bson.codecs.BsonStringCodec.decode(BsonStringCodec.java:28)	at org.bson.codecs.BsonArrayCodec.readValue(BsonArrayCodec.java:102)	at org.bson.codecs.BsonArrayCodec.decode(BsonArrayCodec.java:67)	at org.bson.codecs.BsonArrayCodec.decode(BsonArrayCodec.java:37)	at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:101)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41)	at org.bson.codecs.configuration.LazyCodec.decode(LazyCodec.java:47)	at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:101)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41)	at org.bson.codecs.configuration.LazyCodec.decode(LazyCodec.java:47)	at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:101)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41)	at org.bson.codecs.configuration.LazyCodec.decode(LazyCodec.java:47)	at org.bson.codecs.BsonArrayCodec.readValue(BsonArrayCodec.java:102)	at org.bson.codecs.BsonArrayCodec.decode(BsonArrayCodec.java:67)	at org.bson.codecs.BsonArrayCodec.decode(BsonArrayCodec.java:37)	at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:101)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41)	at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:101)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41)	at com.mongodb.connection.ReplyMessage.
(ReplyMessage.java:51) at com.mongodb.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:301)

根据以上信息,好像是MongoDB查询数据的时候占用内存过大,导致的OOM

导出dump文件并且分析一下 使用MAT打开文件后有个 Problem Suspect 1(最有可能导致内存溢出的提示)

The thread org.apache.tomcat.util.threads.TaskThread @ 0xf9b19fa0 http-nio-8099-exec-8 keeps local variables with total size 58,255,056 (60.49%) bytes.The memory is accumulated in one instance of "java.lang.Object[]" loaded by "
".The stacktrace of this Thread is available. See stacktrace.Keywordsjava.lang.Object[]Details »

点击 See stacktrace

信息量还是很庞大的,慢慢分析。 找到

at com.mongodb.DB.command(Lcom/mongodb/DBObject;Lcom/mongodb/ReadPreference;Lcom/mongodb/DBEncoder;)Lcom/mongodb/CommandResult; (DB.java:496)  at com.mongodb.DB.command(Lcom/mongodb/DBObject;Lcom/mongodb/ReadPreference;)Lcom/mongodb/CommandResult; (DB.java:512)  at com.mongodb.DB.command(Lcom/mongodb/DBObject;)Lcom/mongodb/CommandResult; (DB.java:467)

我们可以发现是执行Mongo命令出的错误,MongoResult,,,这不是返回的Mongo查询结果集吗??难道是返回的结果集过大??很有可能!!! 继续往下看。。。

at com.fosung.data.party.dao.DetailDao.detailQuery(Lcom/fosung/data/party/dto/PartyItemDto;)Lcom/fosung/data/party/vo/OutDetailCountVo; (DetailDao.java:314)  at com.fosung.data.party.dao.DetailDao$$FastClassBySpringCGLIB$$caf49f16.invoke(ILjava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (Unknown Source)

此处看到我们业务代码的方法,很有可能就是此处方法导致的OOM,进一步分析我们的业务方法: 经过我们仔细分析终于找出问题的原因: 上面出现问题的原因是在获取总条数的时候,没有加分页条件(skip和limit)导致查询所有符合条件的记录(符合条件的记录有6w多条),全部加载到内存中,因此导致了OOM问题。

解决: MongoDB使用管道查询后获取符合条件的总条数

db.getCollection('user_order').aggregate([     { "$match" : { "code" : "100002255842358"}} ,      { "$project" : { "code" : 1 , "yearInfo" : 1 , "personInfo" : 1}} ,      { "$unwind" : "$yearInfo.counts"} ,      { "$unwind" : "$yearInfo.counts.code"} ,      { "$match" : { "yearInfo.counts.code" : { "$in" : [ "1"]}}} ,      { "$sort" : { "code" : 1 , "yearInfo.counts.sort" : 1}} ,     { "$lookup" : { "from" : "user_info" , "localField" : "yearInfo.counts.detail" , "foreignField" : "_id" , "as" : "personInfo"}} ,      { "$unwind" : "$personInfo"} ,       {"$group":{"_id":null,"totalCount":{"$sum":1}}},      {"$project":{"totalCount":"$totalCount","_id":0}}    ])

不需要每次去获取所有记录数,再取记录的条数。

修改完后测试完美通过。。。

转载于:https://my.oschina.net/u/2477500/blog/2054701

你可能感兴趣的文章
Java I/O操作
查看>>
Tomcat性能调优
查看>>
Android自学--一篇文章基本掌握所有的常用View组件
查看>>
灰度图像和彩色图像
查看>>
argparse - 命令行选项与参数解析(转)
查看>>
修改上一篇文章的node.js代码,支持默认页及支持中文
查看>>
java只能的round,ceil,floor方法的使用
查看>>
新开的博客,为自己祝贺一下
查看>>
采用JXL包进行EXCEL数据写入操作
查看>>
将txt文件转化为json进行操作
查看>>
线性表4 - 数据结构和算法09
查看>>
我的2014-相对奢侈的生活
查看>>
Java设计模式
查看>>
Spring Cloud 微服务分布式链路跟踪 Sleuth 与 Zipkin
查看>>
华为OJ 名字美丽度
查看>>
微信公众号与APP微信第三方登录账号打通
查看>>
软件工程师成长为架构师必备的十项技能
查看>>
mysql-This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME 错误解决
查看>>
BIEE Demo(RPD创建 + 分析 +仪表盘 )
查看>>
Cocos2dx 3.0开发环境的搭建--Eclipse建立在Android工程
查看>>