一,报错信息:

二,问题定位:这是一个查询功能

三,代码:

public JSONObject selectInvTransactions(InvTransactionsVO invTransactionsVO) {  int pageNum = invTransactionsVO.getPageNum() == null ? 0 : invTransactionsVO.getPageNum();int pageRows = invTransactionsVO.getPageRows() == null ? 0 : invTransactionsVO.getPageRows();        if (pageNum != 0 && pageRows != 0) {PageHelper.startPage(pageNum, pageRows);}List<InvTransactionsEntity> list = invTransactionsMapper.selectInvTransactions(invTransactionsVO);List<InvTransactionsVO> listVO = new ArrayList<InvTransactionsVO>();for (InvTransactionsEntity invTransactionsEntity : list) {InvTransactionsVO invTransactions = new InvTransactionsVO();BeanUtil.getInstance().copyNotNull(invTransactionsEntity, invTransactions);Double a = invTransactionsEntity.getfQty() == null ? 0.000 : invTransactionsEntity.getfQty();Double b = invTransactionsEntity.gettQty() == null ? 0.000 : invTransactionsEntity.gettQty();invTransactions.setInvTransQty(Math.abs(new BigDecimal(a.toString()).subtract(new BigDecimal(b.toString())).doubleValue()));// 变化前库存状态名称Map<String, Object> fStatusNameMap = new HashMap<>();fStatusNameMap.put("dictValue", invTransactions.getfStatus());fStatusNameMap.put("code", DictTypeE.WMS_INVENTORY_TYPE.getTypeCode());// 库存状态fStatusNameMap.put("factoryAreaId", invTransactionsVO.getAreaId());String fStatusName = hystrixWrappedAuthServiceClient.valueToKey(fStatusNameMap);invTransactions.setfStatusName(fStatusName);// 变化后库存状态名称Map<String, Object> tStatusNameMap = new HashMap<>();tStatusNameMap.put("dictValue", invTransactions.gettStatus());tStatusNameMap.put("code", DictTypeE.WMS_INVENTORY_TYPE.getTypeCode());// 库存状态tStatusNameMap.put("factoryAreaId", invTransactionsVO.getAreaId());String tStatusName = hystrixWrappedAuthServiceClient.valueToKey(tStatusNameMap);invTransactions.settStatusName(tStatusName);// 变化前零件状态名称Map<String, Object> fItemStatusNameMap = new HashMap<>();fItemStatusNameMap.put("dictValue", invTransactions.getfItemStatus());fItemStatusNameMap.put("code", DictTypeE.WMS_ITEM_INV_TYPE.getTypeCode());// 零件库存状态fItemStatusNameMap.put("factoryAreaId", invTransactionsVO.getAreaId());String fItemStatusName = hystrixWrappedAuthServiceClient.valueToKey(fItemStatusNameMap);invTransactions.setfItemStatusName(fItemStatusName);// 变化后零件状态名称Map<String, Object> tItemStatusNameMap = new HashMap<>();tItemStatusNameMap.put("dictValue", invTransactions.gettItemStatus());tItemStatusNameMap.put("code", DictTypeE.WMS_ITEM_INV_TYPE.getTypeCode());// 零件库存状态tItemStatusNameMap.put("factoryAreaId", invTransactionsVO.getAreaId());String tItemStatusName = hystrixWrappedAuthServiceClient.valueToKey(tItemStatusNameMap);invTransactions.settItemStatusName(tItemStatusName);// 交易类型名称Map<String, Object> operateTypeNameMap = new HashMap<>();operateTypeNameMap.put("dictValue", invTransactions.getOperateType());operateTypeNameMap.put("code", DictTypeE.WMS_INV_TRANS_TYPE.getTypeCode());// 交易类型operateTypeNameMap.put("factoryAreaId", invTransactionsVO.getAreaId());String operateTypeName = hystrixWrappedAuthServiceClient.valueToKey(operateTypeNameMap);invTransactions.setOperateTypeName(operateTypeName);invTransactions.setfMuLpNo(invTransactionsEntity.getfMuLpNo());invTransactions.settMuLpNo(invTransactionsEntity.gettMuLpNo());SupplierVO supplierVO = hystrixWrappedBizServiceClient.feignSelectById(invTransactionsEntity.getSupplierId());if (supplierVO != null) {invTransactions.setSupplierCode(supplierVO.getCode());}listVO.add(invTransactions);}PageInfo<InvTransactionsEntity> infoEntity = new PageInfo<InvTransactionsEntity>(list);PageInfo<InvTransactionsVO> info = new PageInfo<InvTransactionsVO>(listVO);List<InvTransactionsVO> invTransactionsList = info.getList();JSONObject json = new JSONObject();json.put("result", invTransactionsList);json.put("total", infoEntity.getTotal());return json;}

四:排查方向:

1.应用服务器提示错误的解决:
把启动参数内存值设置足够大。

2.Java代码导致错误的解决:
重点排查以下几点:

1)检查代码中是否有死循环或递归调用。

2)检查是否有大循环重复产生新对象实体。

3)检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询

4 )检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

五:实际分析:

1,JVM堆内存设置过小,有可能

2,该该方法中存在for循环,且循环中大量创建对象,可能

3,一次查询过多数据,已分页,排除

4,List未释放,一般都不释放,不太可能

六,实际定位:

1,查询GC日志:

日志内容:

但此时只知道该时间点发生GC了,并不能直接定位到是具体哪里导致内存溢出。是可以该时间点再去查看日志文件,查找执行哪一个方法时发生内存溢出,以此来定位方法。其实日志文件报错信息中已经抛出了哪个方法,也无需根据gc文件定位出错方法。

2,

查询服务进程:ps -ef|grep java

查看服务内存信息:

通过以上信息可以看到,堆内存分配大小约为3G,整个内存大小为15G。

3,循环中创建了大量对象,可以优化这个地方,上面查询返回vo,循环中不创建对象。

七,思考误区,问题准确定位

之前分析:从报错信息看,报的是查询路径,推断是查询导致的,内存溢出。然后分析查询方法,因为用的分页查询,每次查询的只是一页的十条内容,for循环中也是十条,所以在里面创建对象也不会导致内存溢出,量小。点击下一页,重新掉、调用方法,对象会被回收。

误区:当时怀疑是导出导致的,因为导出数据比较多,达20万以上。但是抛出异常的地址,是查询,不是导出,就排除了这个原因,而且在本地测试导出的时候也没有坚持导完看结果,就没定位到问题。实际上,导出也调用了查询方法,抛出查询地址当然正常。

实际定位:还是把生产的大量数据导入测试环境库,测试导出,大概20分钟后,问题重现了,测试服务挂了,日志错误与生产出现的一致,由此定位到为题。

原因:导出的数据量很大,方法未结束,for循环中创建对象无法被释放。

优化:查询返回vo,避免在循环中创建对象。

八,举一反三,总结

1,类似问题如何解决:从报错信息,定位方法;把生产数据拉到测试环境测试;用过top,jmap,查看内存变化,对象数量变化。

2,不要把问题想的这么绝对,多想一步。

3,动手,实践,动手,实践,动手,实践。

一次生产内存溢出记录相关推荐

  1. 生产内存溢出定位分析

    生产内存溢出定位分析 具体生产环境大多为linux系统,此处以linux系统为示例. 1.什么是oom? 英文全称"Out Of Memory",译为 "内存不足&quo ...

  2. 生产内存溢出,通过jprofiler对dump文件进行分析

    选择"Open Snapshot",点击"Open a single Snapshot "加载dump文件. 若dump文件jProfiler无法识别,则可以直 ...

  3. Node.js 应用故障排查手册 —— 冗余配置传递引发的内存溢出

    楔子 前面一小节我们以一个真实的压测案例来给大家讲解如何利用 Node.js 性能平台 生成的 CPU Profile 分析来进行压测时的性能调优.那么与 CPU 相关的问题相比,Node.js 应用 ...

  4. node aws 内存溢出_在AWS Elastic Beanstalk上运行生产Node应用程序的现实

    node aws 内存溢出 by Jared Nutt 贾里德·努特(Jared Nutt) 在AWS Elastic Beanstalk上运行生产Node应用程序的现实 (The reality o ...

  5. 生产环境 JVM 内存溢出案例分析

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:blog.csdn.net/prestigeding ...

  6. 生产环境JVM内存溢出案例分析

    如果我们所在公司的业务量比较大,在生产环境经常会出现JVM内存溢出的现象,那我们该如何快速响应,快速定位,快速恢复问题呢? 本文将通过一个线上环境JVM内存溢出的案例向大家介绍一下处理思路与分析方法. ...

  7. 生产环境JVM内存溢出案例分析!

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:Nginx 为什么快到根本停不下来? 个人原创100W+访问量博客:点击前往,查看更多 来源:blog.csdn ...

  8. openjdk platform binary 内存_记一次内存溢出导致的生产事故

    背景 因为同事的离职,半路被迫接手的一个可视化项目,使用ElasticSearch作为OLAP数据库.Docker作为部署工具等,突然有一天项目现场环境出现JVM内存溢出问题,被迫披挂上阵定位问题的原 ...

  9. 【Android-NCNN-Vulkan】记录一次ncnn-vulkan在低性能开发板上出现的native内存溢出的问题

    模型作用:人脸关键点检测 原模型:tensorflow pb.model 转化后:ncnn *.param *.model 主干网络:shufflenet v2 CPU:ARM A53 2.0GHz ...

  10. 生产环境频繁内存溢出,原来就是因为这个“String类”

    本文分享自华为云社区<[高并发]你敢信?String类竟然是导致生产环境频繁内存溢出的罪魁祸首!!>,作者:冰河  . 最近,一名小伙伴跟我说:他写的程序在测试环境一点问题没有,但是发到生 ...

最新文章

  1. 【OpenCV 4开发详解】图像与视频的保存
  2. Could not get dialect instance.
  3. mysql索引commit卡死_mysql 5.6 read-committed隔离级别下并发插入唯一索引导致死锁一例...
  4. CTEX - 在线文档 - TeX/LaTeX 常用宏包
  5. BigData之Hadoop:Hadoop的简介、深入理解、下载、案例应用之详细攻略
  6. 饭后为什么不宜喝冷饮?
  7. openresty获取nginx请求头信息
  8. boost使用split分割字符串
  9. centos 安装oracle java,CentOS 4.4下安装Oracle 10
  10. mybatis动态sql传ist集合參与传数组参数
  11. python删除指定字符_python删除字符串中指定字符的方法
  12. 【渝粤教育】国家开放大学2018年春季 0551-21T素描(二) 参考试题
  13. 实现类似黑客帝国的字符流特效屏保
  14. 嘻哈电音综合插件-Digikitz Linked Linked Vibes Workstation WiN-MAC
  15. 视频中的I、P、B帧
  16. 年轻人最好要接触」的东西
  17. 山东省深化农村公路管理养护体制改革实施方案
  18. 案例研究:使用 ETW 和 Netmon 解决未知 USB 设备的问题
  19. 笔记本电脑上的触摸板怎样关闭(神州战神)
  20. 用Python处理EXCEL表格(Openpyxl)

热门文章

  1. shell脚本显示颜色的设置
  2. 云计算里AWS和Azure的探究(3)
  3. Delphi编写事件模型客户端(3)
  4. java集群之间共享数据_多个JVM之间,数据共享的问题?
  5. Linux触摸屏驱动分析(6410) -- s3c-ts
  6. 传输层协议(3):TCP 连接(中)
  7. 抓包工具tcpdump的使用总结(持续更新)
  8. Freeswitch与外域IP对接之incoming call
  9. 什么是 SNMP 和 MIB
  10. python入口文件_python常用模块:项目目录规范、定制程序入口、自定义模块、引用变量、time和datetime模块...