Spring Boot应用程序浪费了内存

内存是当今世界上被广泛浪费的资源之一。 由于编程效率低下,令人吃惊的(有时是“令人震惊的”)内存浪费被浪费了。 我们看到这种模式在多个企业应用程序中重复出现。 为了证明这种情况,我们进行了一项小型研究。 我们分析了著名的spring boot pet诊所应用程序,以查看浪费了多少内存。 该应用程序是由社区设计的,旨在显示spring应用程序框架如何用于构建简单但功能强大的面向数据库的应用程序。

环境

  • Spring Boot 2.1.4。发布
  • Java SDK 1.8
  • 的Tomcat 8.5.20
  • 带有MySQL Connector / J 8.0.15的MySQL 5.7.26

压力测试

我们使用了流行的开源负载测试工具Apache JMeter进行压力测试。 我们使用以下设置执行了30分钟的负载测试:

  • 线程数(用户)– 1000(连接到目标的用户数)
  • 加速周期(以秒为单位)– 10.所有请求开始的时间范围。 根据我们的配置,每0.01秒,将启动1个新线程,即100个线程/秒。
  • 循环计数–永远。 这1000个线程背对背执行测试迭代。
  • 持续时间(秒)-1800。 加速后,1000个线程连续运行1800秒。
图:Jmeter设置

我们在负载测试中采用了以下方案:  

  • 将新的宠物主人添加到系统。
  • 查看有关宠物主人的信息。
  • 向系统添加新宠物。
  • 查看有关宠物的信息。
  • 将有关访问的信息添加到宠物的访问历史中。
  • 更新有关宠物的信息。
  • 更新有关宠物主人的信息。
  • 通过搜索其姓名查看所有者信息。
  • 查看所有所有者的信息。

如何测量内存浪费?

工业界有数百种工具可以显示所使用的内存量 。 但是我们很少遇到能够测量由于编程效率低下而浪费的内存量的工具。 HeapHero是一个简单的工具,可以分析堆转储并告诉您由于编程效率低而浪费了多少内存。

测试运行时,我们从Spring Boot Pet Clinic应用程序捕获了堆转储。 (有7种不同的选项可从Java / Android应用程序 捕获堆转储 。您可以选择最方便的选项)。

我们将捕获的堆转储上传到HeapHero工具中。 工具生成了这个漂亮的报告,显示由于效率低下的编程浪费了65%的内存。 是的,这是一个简单的原始应用程序,应该在其中实现了所有最佳实践,在一个著名的框架上也浪费了65%的内存。

图:由HeapHero生成的图表,显示65%的内存被Spring Boot宠物诊所应用程序浪费了

分析内存浪费

从报告中,您可以注意到以下内容:

  • 字符串重复导致浪费了15.6%的内存
  • 由于原始数组效率低下,浪费了14.6%的内存
  • 由于重复的原始数组浪费了14.3%的内存
  • 由于收集效率低下,浪费了12.1%的内存

在此Spring启动应用程序 (和大多数企业应用程序)中浪费内存的主要原因是字符串重复。 该报告显示了由于重复字符串而浪费了多少内存,它们是什么字符串,谁在创建它们以及如何对其进行优化。

无花果:重复的字符串

您会注意到由于重复的字符串浪费了15.6%的内存。 请注意

  • 'Goldi'字符串已被创建207,481次。
  • “访问”字符串已创建132,308次。 “访问”是我们在测试脚本中提到的描述。
  • “班加罗尔”字符串已创建75,374次。 “ Banglore”是我们在测试脚本中指定的城市名称。
  • '123123123'已被创建37,687次。
  • “ Mahesh”字符串已创建37,687次。

显然,“ Goldi”是通过测试脚本在屏幕上输入的宠物的名称。 “访问”是通过测试脚本在屏幕上输入的描述。 同样,是值。 但是有一个问题,为什么要创建相同的字符串对象那么几千次。

我们都知道字符串是不可变的(即一旦创建,就无法修改)。 鉴于为什么要创建成千上万个重复的字符串?

HeapHero工具还报告创建这些重复字符串的代码路径。

无花果:重复字符串源自的代码路径

这是修复应用程序中重复字符串的高级建议 。 您可以采用适用于您的应用程序的策略。

在弹簧靴宠物诊所应用中造成内存浪费的另一个主要原因是收集效率低下。 以下是HeapHero报告的摘录:

图:由于收集效率低而浪费的内存

您会注意到,内存中99%的LinkedHashSet中没有任何元素。 如果没有元素,为什么还要创建LinkedHashSet? 当您创建一个新的LinkedHashSet对象时,将在内存中保留16个元素的空间。 现在为这16个元素保留的所有空间都被浪费了。 如果对LinedHashset进行延迟初始化,则不会出现此问题。

不良做法:

 private LinkedHashSet<String, String>myHashSet = new LinkedHashSet();  public void addData(String key, String value) {  myHashSet.put(key, value);  } 

最佳实践:

 private LinkedHashSet<String, String>myHashSet;  public void addData(String key, String value) { If (myHashSet == null ) {  myHashSet = new LinkedHashSet(); }  myHashSet.put(key, value);  } 

同样,另一个观察结果是:68%的ArrayList中仅包含1个元素。 创建ArrayList对象时,将在内存中保留10个元素的空间。 这意味着在88%的ArrayList中9个元素的空间被浪费了。 如果可以使用容量初始化ArrayList,则可以避免此问题。

不良做法:使用默认值初始化集合。

 new ArrayList(); 

最佳实践:使用容量初始化集合

 new ArrayList( 1 ); 

内存不便宜

一个人可以反驳说,内存是如此便宜,那么为什么我要担心它呢? 公平的问题。 但是在云计算时代,我朋友的记忆并不便宜。 有4种主要的计算资源:

  1. 中央处理器
  2. 记忆
  3. 网络
  4. 存储

您的应用程序可能在AWS EC2实例上运行的数十万个应用程序服务器上运行。 在上述4种计算资源中,哪个资源在EC2实例中已饱和? 我要求您在这里稍等一下,然后再继续阅读。 考虑一下,首先确定哪些资源已饱和。

对于大多数应用程序,它是*内存*。 CPU始终为30 – 60%。 总是有大量的存储空间。 很难饱和网络(除非您的应用程序正在流式传输大量视频内容)。 因此,对于大多数应用程序来说,首先是内存饱和。 即使CPU,存储和网络未充分利用,仅由于内存变得饱和,您最终还是会配置越来越多的EC2实例。 这将使您的计算成本增加几倍。

另一方面,由于编程效率低下,现代应用程序无一例外地浪费了30%-90%的内存。 即使在没有太多业务逻辑的Spring Boot宠物诊所之上,也浪费了65%的内存。 实际的企业应用程序将浪费相似的数量,甚至更多。 因此,如果您可以编写内存有效的代码,那么它将降低您的计算成本。 由于内存是第一个达到饱和的资源,因此,如果可以减少内存消耗,则可以在较少数量的服务器实例上运行应用程序。 您也许可以减少30 – 40%的服务器。 这意味着您的管理层可以减少30%-40%的数据中心(或云托管提供商)成本,再加上维护和支持成本。 它可以节省数百万/数十亿美元的成本。

结论

除了减少计算成本,编写内存效率高的代码后,您的客户体验也将变得更好。 如果您可以减少为服务新的传入请求而创建的对象数量,则响应时间将大大缩短。 由于创建的对象较少,因此在创建和垃圾回收对象上将花费较少的CPU周期。 减少响应时间将提供更好的客户体验。

翻译自: https://www.javacodegeeks.com/2019/11/memory-wasted-by-spring-boot-application.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341184.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Win10灵活使用快速访问

I 快速访问视图 位置在winE 左侧窗口&#xff0c;点击可快速到达某个特定的文件夹。作用类似于快捷方式&#xff0c;操作简单。 II 关闭自动添加 默认是显示经常使用的文件夹。这使得窗口内文件夹较乱。 通过以下设置&#xff0c;关闭自动显示 1. 2.把框内√去掉 III 固定文…

activemq网络桥接_ActiveMQ –经纪人网络解释–第2部分

activemq网络桥接在此博客中&#xff0c;我们将看到双工网络连接器如何工作。 在上一部分中&#xff0c;我们从broker-1和broker-2创建了一个网络连接器。 我们能够看到&#xff0c;当代理2上有一个使用者使用队列“ foo.bar”时&#xff0c;代理1上的队列“ foo.bar”的消息如…

Apache Lucene中的并发查询执行

Apache Lucene是一个出色的并发纯Java搜索引擎&#xff0c;如果您愿意&#xff0c;它可以轻松地使服务器上的可用CPU或IO资源饱和。 “典型” Lucene应用程序的并发模型在搜索时每个查询一个线程&#xff0c;但是您知道Lucene还可以使用多个线程同时执行一个查询以大大减少最慢…

Windows设置自己的程序开机自动启动

Windows系统想要快速设置开机自动启动某个程序&#xff0c;可以使用以下方法设置&#xff1a; 1.找到启动文件夹 CtrlR 打开运行&#xff0c;输入shell:startup&#xff0c;回车,找到启动文件夹 2.拷贝需要开机启动的程序的快捷方式到此文件夹即可。 3.打开任务管理器-启动查…

Citavi中文件管理

目录 I 文献相对应的PDF文件相关操作 1 打开PDF所在位置 2 直接重命名PDF文献 注&#xff1a;设置角标方式 II 阅读文献相关的文件的添加与删除 1 添加 2 删除 III PPT CAJ文件的添加 I 文献相对应的PDF文件相关操作 PDF文件可直接拉入文献框进行导入 1 打开PDF所在位置…

Citavi插件的安装和使用以及注意事项

【文章转载于知乎大神&#xff1a;Citavi插件的安装和使用以及注意事项 - 知乎】 没有软件是十全十美的&#xff0c;基础功能够用&#xff0c;附加功能以插件、脚本的方式来支持是个不错的思路。 Citavi提供了自定义宏和插件的方式&#xff0c;来满足更为复杂的格式修整和文献…

MiUI特色功能设置总结

一 常用设置 【转载于知乎https://www.zhihu.com/question/514792652/answer/2377622710】 1 自动优化系统 其实在手机开发者模式设置中&#xff0c;有2个地方我们需要设置&#xff0c;设置了不仅可以让手机运行更流畅&#xff0c;而且还能帮我们自动优化系统。 &#xff0…

potplayer怎么设置无边框播放,播放时隐藏进度条

potplayer默认情况下播放视频时会显示边框&#xff0c;那么怎么设置无边框播放呢?下面小编就为大家详细的介绍一下&#xff0c;大家感兴趣的话就一起来了解下吧! potplayer怎么设置无边框播放?potplayer设置无边框播放方法 1、点击左上角的potplayer 2、在下拉菜单中点击选项…

蓝牙播放Stereo和Hands-Free AG Audio两种模式的区别?

当使用蓝牙耳机时&#xff0c;发现电脑的播放设备显示了两种模式&#xff08;如下图所示&#xff09;&#xff0c;Stereo模式下声音正常&#xff0c;而调到Hands-Free AG Audio模式下声音频带窄了很多且音质差&#xff0c;典型的电话音&#xff0c;下面具体说说这两种模式的区别…

workrave使用方法

一 模式介绍 阅读模式&#xff1a; 不论电脑什么状态&#xff0c;倒计时一直进行 普通模式&#xff1a; 当检测到电脑没有任何操作&#xff0c;比如打字与移动鼠标&#xff0c;则暂停倒计时。如果长时间没有操作&#xff0c;则默认进入休息状态&#xff0c;下次移动鼠标&…

OpenJDK织机和结构化并发

Project Loom是Hotspot Group赞助的项目之一&#xff0c;旨在向JAVA世界提供高吞吐量和轻量级的并发模型。 在撰写本文时&#xff0c;Loom项目仍处于积极开发中&#xff0c;其API可能会更改。 为什么要织机&#xff1f; 每个新项目可能会出现的第一个问题是为什么&#xff1f;…

设置花里胡哨的Xshell字体与背景颜色(超全)

大部分运维和开发经常接触到的客户端连接工具很多都是Xshell&#xff0c;但是经常看到别人的背景色和字体都是五颜六色&#xff0c;还有护眼色的背景&#xff08;想必大家也会遇到在深夜加班时为了不打扰身边小伙伴的休息不开灯&#xff0c;打开Xshell时可以闪瞎人眼的白色背景…

Ubuntu “sudo apt-get update”报错

一 sudo apt-get update作用 从服务器拉取可用的包到本地 二 出错情况 Ign:9 https://download.sublimetext.com apt/stable/ Packages Ign:10 https://download.sublimetext.com apt/stable/ Translation-en_US Ign:11 https://download.sublimetext.com apt/stable/ Transl…

add-apt-repository命令详解

该命令是通过PPA源方式安装软件的添加PPA源到Source list中的命令&#xff0c;该软件安装方式的流程为&#xff1a; 1.搜索PPA软件源&#xff0c;如在Google上软件名称关键字 PPA &#xff0c;或者也可直接到 launchpad.net 上搜索2.sudo apt-add-repository ppa_source_name…

如何在Java中修复表达式的非法开头

您是否遇到过这个令人难以置信的错误&#xff0c;想知道如何解决它&#xff1f; 让我们浏览一下这篇文章&#xff0c;研究如何解决表达式Java非法开头错误。 这是一个动态错误&#xff0c;这意味着编译器会发现某些不符合Java编程规则或语法的内容。 初学者大多会遇到Java中的…

apt-get install 和pip install 、 apt与apt-get之间的区别 的区别

1 apt-get install 和pip install 的区别 区别&#xff1a; pip install 主要安装pypi上已经上传的包或库&#xff0c;主要和编程语言python 有关的包&#xff0c;可以选择版本&#xff0c;或者在已有的新版本上安装旧版本sudo apt-get install 是用于系统升级下载相关的软件…

在Word中如何调整编号和文字之间的间距?

https://jingyan.baidu.com/article/48b558e32a80b53e39c09a77.html 首先&#xff0c;打开或者新建一份需要编辑的Word文档。如图&#xff1a; 2 接着&#xff0c;选中需要调整编号与文字之间间距的文字。如图&#xff1a; 3 接着&#xff0c;右键单击鼠标&#xff0c;在弹…

将Spock 1.3测试迁移到Spock 2.0

了解Spock 2.0 M1&#xff08;基于JUnit 5&#xff09;的期望&#xff0c;如何在Gradle和Maven中迁移到它以及为什么报告发现的问题很重要&#xff1a;&#xff09;。 重要说明 。 我绝对不建议您永久将您的现实项目迁移到Spock 2.0 M1&#xff01; 这是2.x的第一个&#xff0…

Word使用中常用的快捷键

1. 字体放大缩小 Ctrl ] 放大字体 Ctrl [ 缩小字体 选中文本&#xff0c;按快捷键即可看到效果。 2 对齐文本 左对齐&#xff1a;Ctrl L 右对齐&#xff1a;Ctrl R 居中对齐&#xff1a;Ctrl E 3 符号上下标 下标&#xff1a;【Ctrl】【】 上标&#xff1a;【C…

创建快捷方式时如何不带“快捷方式“后缀字样?

方法一&#xff1a; 去除“快捷方式”字样的方法&#xff1a; 创建快捷方式&#xff0c;使用上述方法比较繁琐&#xff0c;我们往往直接右击要创建快捷方式的文件或文件夹&#xff0c;然后“发送到”→“桌面快捷方式”。这样创建的&#xff0c;还会带“快捷方式”字样&#xf…