这将是另一个故事,与我们分享有关内存相关问题的最新经验。 该案例是从最近的客户支持案例中提取的,在该案例中,我们遇到了一个行为异常严重的应用程序,该应用程序因生产中的OutOfMemoryError消息而死亡。 在连接了Plumbr的情况下运行应用程序之后,我们确定这次不会遇到内存泄漏。 但是仍然有一些严重的错误。

症状是通过监视某些数据结构的开销的一项实验功能发现的。 它给了我们一个信号,指出了源代码中的一个特定位置。 为了保护客户的隐私,我们使用合成样本重新制作了案件,同时在技术上使其与原始问题相同。 随时下载源代码 。

我们发现自己盯着从外部源加载的一组对象。 与外部系统的通信是通过XML接口实现的。 这本身还不错。 但是,集成实现细节分散在整个系统中(将收到的文档转换为XMLBean实例,然后在整个系统中使用)的事实可能并不是最明智的选择。

本质上,我们正在处理延迟加载的缓存解决方案。 缓存的对象是人物:

// Imports and methods removed to improve readability
public class Person {
private String id;
private Date dateOfBirth;
private String forename;
private String surname;
}

不太可能消耗内存。 但是,当我们打开一些更多的细节时,情况看起来会变得有些酸。 也就是说,该数据的实现类似于上面的简单类声明。 相反,该实现使用了模型生成的数据结构。 使用的模型类似于以下简化的XSD代码段:

<xs:schema targetNamespace="http://plumbr.eu"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:string"/>
<xs:element name="dateOfBirth" type="xs:dateTime"/>
<xs:element name="forename" type="xs:string"/>
<xs:element name="surname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

开发人员使用XMLBeans生成了在后台使用的模型。 现在让我们添加一个事实,即缓存应该容纳多达130万个Persons实例,并且我们为失败奠定了坚实的基础。

运行捆绑的测试用例表明,基于XMLBean的解决方案的130万个实例将消耗大约1.5 GB的堆。 我们认为我们可以做得更好。

第一个解决方案是显而易见的。 集成细节不应跨越系统边界。 因此,我们将缓存解决方案更改为简单的java.util.HashMap <Long,Person>解决方案。 以ID为键,以Person对象为值。 立刻我们发现内存消耗减少到214MB 。 但是我们还不满意。

由于Map中的键本质上是数字,因此我们有所有理由使用Trove Collections来进一步减少开销。 实现中的快速更改,我们已用TLongObjectHashMap <Person>替换了HashMap 。 堆消耗降至143MB

我们当然可以在这里停下来,但是出于工程方面的好奇心,我们不允许这样做。 我们不禁注意到所使用的数据包含冗余信息。 出生日期实际上是在ID中编码的,因此我们可以轻松地从给定的ID计算生日,而不是将其复制到其他字段中。

因此,我们更改了Person对象的布局,现在它仅包含以下字段:

// Imports and methods removed to improve readability
public class Person {
private long id;
private String forename;
private String surname;
}

重新运行测试证实了我们的期望。 堆消耗降至93MB 。 但是我们仍然不满意。

该应用程序在具有旧JDK6版本的64位计算机上运行。 默认情况下不压缩普通对象指针。 切换到-XX:+ UseCompressedOops给了我们额外的胜利-现在我们的内存已减少到73MB

我们可以走得更远,开始实习字符串或基于键构建b树,但这已经开始影响代码的可读性,因此我们决定在这里停止。 21.5倍的堆减少应该已经足够好了。

得到教训?

  • 不要让集成细节跨越系统边界
  • 冗余数据将耗资巨大。 尽可能删除冗余。
  • 原始人是您的朋友。 了解您的工具并学习Trove(如果您还没有的话)
  • 注意JVM提供的优化技术

如果您对进行的实验感到好奇,请随时从此处下载使用的代码 。 描述了用于测量的实用程序,并在此博客文章中提供了该实用程序。

参考: Plumbr博客博客上的JCG合作伙伴 Nikita Salnikov Tarnovski 减少了20倍的内存消耗 。

翻译自: https://www.javacodegeeks.com/2013/06/reducing-memory-consumption-by-20x.html

将内存消耗减少20倍相关推荐

  1. spark减少内存消耗_将内存消耗减少20倍

    spark减少内存消耗 这将是另一个故事,与我们分享有关内存相关问题的最新经验. 该案例是从最近的客户支持案例中提取的,在该案例中,我们遇到了一个行为异常严重的应用程序,该应用程序因生产中的OutOf ...

  2. python减小内存占用_如何将Python内存占用缩小20倍?

    当程序执行过程中RAM中有大量对象处于活动状态时,可能会出现内存问题,特别是在对可用内存总量有限制的情况下. 下面概述了一些减小对象大小的方法,这些方法可以显著减少纯Python程序所需的RAM数量. ...

  3. 朱俊彦团队提出GAN压缩算法:计算量减少20倍,生成效果不变,GPU、CPU统统能加速...

    边策 鱼羊 发自 凹非寺 量子位 报道 | 公众号 QbitAI 现如今,GAN的效果已经越来越出神入化. 比如英伟达的GauGAN,就如神笔马良,能够凭空造物: 不过,从无化有背后,计算量也相当惊人 ...

  4. python使用函数可以减少内存吗_如何将Python内存占用缩小20倍?

    当程序执行过程中RAM中有大量对象处于活动状态时,可能会出现内存问题,特别是在对可用内存总量有限制的情况下. 下面概述了一些减小对象大小的方法,这些方法可以显著减少纯Python程序所需的RAM数量. ...

  5. Docker中的Java内存消耗优化以及我们如何使用Spring Boot

    ---- / BEGIN/ ---- 如果您的Docker容器占用太多内存而无法达到最佳性能,请阅读下文以了解一个团队如何找到解决方案. 最近,我所在的团队在部署我们的微服务(AWS上Docker中的 ...

  6. 评测称IE8成内存消耗王 高出IE7一半 为火狐2倍

    美国软件公司Devil Mountain Software日前对微软上周发布的IE8 Beta2进行了评测.评测结果显示,目前版本的IE8在数款主流浏览器中是"内存消耗王". 评测 ...

  7. python内存消耗大吗_如何减少python内存的消耗?

    标签: Python 打算删除大量涉及像C和C++语言那样的复杂内存管理.当对象离开范围,就会被自动垃圾收集器回收.然而,对于由Python 开发的大型且长期运行的系统来说,内存管理是不容小觑的事情. ...

  8. 实例解读:如何减少Docker中的Java内存消耗

    最近,我所在的团队面临着部署微服务(Java+SpringMVC in Docker on AWS)的问题.主要问题是,很多非常轻巧的应用程序消耗了太多的内存.因此,我们经过多方尝试找到了在Docke ...

  9. 串行内存消耗 并行内存_如何估算内存消耗?

    串行内存消耗 并行内存 这个故事可以追溯到至少十年之前,当时我第一次接触PHB时遇到一个问题:"在生产部署中,我们需要购买多大服务器". 我们正在构建的新的,闪亮的系统距离生产开始 ...

最新文章

  1. Xshell、Xftp入门使用
  2. attachment old API read - DB debug
  3. Javascript 检测 页面是否在iframe中
  4. SpringBootAdmin服务端
  5. mhd格式三维图像显示_给你的家乡做个三维地图模型,满满的成就感,快来学习下...
  6. python3.6字典有序_为什么Python 3.6以后字典有序并且效率更高?
  7. 【英语学习】【WOTD】veritable 释义/词源/示例
  8. echo输出换行_Bash shell教程[5] echo命令
  9. 第10题 正则表达式匹配(动态规划)
  10. 计算机应软件与理论学什么,计算机软件与理论
  11. C++迭代器(STL迭代器)
  12. SCM供应链协同管理系统解决方案
  13. 解决Jenkins集成SonarQube Scanner出现“Tasks support was removed in SonarQube 7.6.”的问题
  14. 【web前端期末大作业】简单的学生网页作业源码 基于html css javascript jquery技术设计的音乐网站(44页)
  15. 电视剧的收视排行榜(Python)
  16. window7电脑如何调亮度
  17. 一篇搞懂OOA/OOD/OOP的区别
  18. 计算机网络第七版 谢希仁 3-33答案
  19. linux 进程rt,RTLinux进程调度策略总结
  20. 将BMP 格式图片转换为 JPEG 格式【c语言】

热门文章

  1. 中国有超级计算机的大学,计算机专业排名看超算实力,ASC竞赛五大高校排名,中山大学第一...
  2. sam+matlab,Sam版Matlab粒子群PSO工具已经更新
  3. ReviewForJob——java虚拟机的垃圾回收策略(个人总结)
  4. 数据库编程——intro to JDBC
  5. spring-boot--整合thymeleaf模板
  6. java 管理多个进程_管理多个Java安装
  7. caffeine 缓存_使用Caffeine和Spring Boot的多个缓存配置
  8. spring 启动加载数据_12个很棒的Spring数据教程来启动您的数据项目
  9. java jsf_将Java 8日期时间API与JSF和Java EE 7结合使用
  10. OAuth 2.0 Java指南:5分钟保护您的应用程序安全