2

应用程序的内存是大还是小?

 8 months ago
source link: https://www.diguage.com/post/large-or-small-memory-size-for-my-app/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

应用程序的内存是大还是小?

2024-01-06
应用程序的内存是大还是小?

应该在内存容量大的少量实例(即机器)上运行应用程序,还是在内存容量小的大量实例上运行应用程序?哪种策略是最佳的?这个问题可能会经常遇到。在开发应用程序长达 20 年,且构建了 JVM 性能工程/故障排除工具( GCeasyFastThread,HeapHero)之后,我仍然不知道这个问题的正确答案。同时,我相信这个问题也没有非黑即白的答案。在本文中,我想与大家分享一下我对这个问题的看法和经验。

两个数十亿美元企业的故事

由于我们的 JVM 性能工程/故障排除工具已广泛应用于各大企业,因此我有机会看到世界级企业应用的实际实施情况。最近,我有机会参观了两家高速成长的科技公司(如果我说出他们的名字,读这篇文章的人都会知道)。这两家公司的总部都在硅谷。它们的业务是技术,因此在工程设计方面很有一套。它们是华尔街的宠儿,享有极高的估值。它们的市值高达数十亿美元。它们是现代企业蓬勃发展的典型代表。在我们的对话中,让我们称这两家企业为公司 A 和公司 B。

在内存大小方面,两家企业都采用了两个极端,这让我感到非常惊讶。公司 A 将堆大小(即 -Xmx)设置为 250GB,而公司 B 则将堆大小设置为 2GB:公司 A 的堆大小是公司 B 的 125 倍。两家公司都对自己的内存大小设置很自信。俗话说:"事实胜于雄辩",两家企业都在扩大规模,处理数十亿的关键业务交易。

两家公司都从事相同的业务,收入/市值大致相同,位于同一地理区域,在同一时间点采用两种极端的内存大小,这真是一次绝佳的体验。鉴于这种现实生活中的真实经验,正确的答案是什么?大内存还是小内存?我的结论是:如果你有一支优秀的团队,采用这两种策略都能取得成功。

大内存容量可能很昂贵

与内存容量小、实例数量多的情况相比,内存容量大、实例(即机器)数量少的情况往往成本较高。以下是基于美国东部(弗吉尼亚州北部)地区 AWS EC2 实例成本的简单计算:

m4.16xlarge - 256GB 内存 - Linux 按实例收费:3.2 美元/小时

T3a small - 2GB 内存 - Linux 按实例收费:0.0188 美元/小时

因此,要获得 256GB 内存容量,我们必须获得 128 个 “T3a small” 实例(即 128 个实例 x 2GB = 256GB)。

128 x T3a small - 2GB 内存 - Linux 按实例收费:2.4064 美元/小时(即 128 x 0.0188 美元/小时)

这意味着内存容量大、实例少的成本比内存容量小、实例多的成本高出 0.793 美元/小时(即 3.2 美元 - 2.4064 美元)。换句话说,"大内存、少实例 "策略的成本要高出 33%

当然,也可以提出另一种反驳意见:如果机器数量较少,可能需要更少的工程师、更少的电力、更少的不动产。服务器的修补和升级也会更容易。

在某些情况下,业务本身的性质决定了应用程序的内存大小。下面是我们遇到的一个真实事件:当我们构建 HeapHero(堆转储分析工具)时,我们工具的内存大小必须大于其解析的堆转储文件。假设堆转储文件大小为 100GB,那么 HeapHero 工具的内存大小必须大于 100GB。别无选择。

假设你要缓存大量数据(比如 200GB),以最大限度地提高应用程序的性能,那么你的堆大小必须大于 200GB。你别无选择。因此,在某些情况下,业务需求将决定内存大小。

性能与故障排除

如果内存大小较大,那么垃圾回收停顿时间通常也会较长。垃圾回收是在应用程序中运行的一个进程,用于清理内存中未引用的对象。如果内存大小很大,那么内存中的垃圾量也会很大。因此,清理垃圾所需的时间也会很长。垃圾回收运行时,应用程序会停顿。不过,这个问题也有解决办法:

  • 您可以使用无暂停 JVM(如: Azul) [1]。

  • 需要进行适当的 GC 调优以减少暂停时间。

同样,如果需要排除任何内存问题,就必须捕获应用程序的堆转储。堆转储基本上是一个文件,其中包含有关应用程序内存的所有信息,如存在哪些对象、它们的引用是什么、每个对象占用多少内存等等。大内存容量应用程序的堆转储也往往非常大。分析大容量堆转储也很困难。即使是世界上最好的堆转储工具,如 Eclipse Memory Analyzer(MAT)HeapHero,在解析超过 100GB 的堆转储时也会遇到非常大的挑战和困难。在测试实验室重现这些问题、存储这些堆转储文件、共享这些堆转储文件都是极大的挑战。

情感第一,理由第二

当阅读了乔纳·莱勒(Jonah Lehrer)撰写的 《为什么大猩猩比专家高明》 等书籍后,我相当确信,你先前的经验和情感在决定应用程序内存大小方面起着关键作用。我曾在一家大型金融机构工作。这家金融机构的首席架构师建议我们使用超大内存运行 JVM,他给出的理由是:“我们以前运行大型主机时,内存也非常大”😊。

如果你在大型企业工作,那么 99.99% 的可能性是你可能无权决定应用程序的内存大小。因为坐在象牙塔里的精英/半仙们已经做出了决定😊。可能很难扭转或改变这一决定。 但如果你有选择或选项来做出决定,那么你对内存大小的决定很可能会受到你之前的经验和情绪的影响 😊。但无论如何,只要你有合适的团队,就不会出错(即选择内存容量大的少量实例或内存容量小的大量实例)。


1. D瓜哥注: 现在也可以使用 OpenJDK 11+,尤其是 OpenJDK 17+

看在D瓜哥码字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

微信打赏码
支付宝打赏码

欢迎关注D瓜哥的微信公众号,在公众号可以获取我的微信二维码:

微信公众号
公众号的微信号是: jikerizhi。如果图片加载不出来,可以直接通过搜索公众号的微信号来查找D瓜哥的公众号。
来说两句吧...
我来说两句

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK