亲爱的 KV,
我一直在处理一个用 Java 编写的大型程序,它似乎大部分时间都在要求我重启它,因为它内存不足。我不确定这是我使用的 JVM(Java 虚拟机)的问题还是程序本身的问题,但在这些频繁的重启过程中,我一直在想为什么这个程序如此臃肿。我本以为 Java 的垃圾回收器会防止程序耗尽内存,尤其是在我的台式机有相当多内存的情况下。 看起来 8 GB 似乎已经不足以处理现代 IDE 了。
RAM 不足
亲爱的 Lack,
八千兆字节?!这就是你拥有的全部? 你是在电脑坟场的沙漠荒原给我写信吗?在我们这个现代时代,任何神志正常的人都不会运行少于 48 GB 内存的机器,至少任何想要运行某些非常特殊的 Java 代码的人都不会。
虽然我很乐意花几百字来抨击 Java——因为,像所有语言一样,它有很多缺点——但你看到的问题可能与垃圾回收器中的 bug 无关。 这与你正在运行的代码中的 bug 以及人类思维中某个根本的 bug 有关。 我将依次解决这两个问题。
代码中的 bug 很容易描述。 任何将内存管理从程序员手中夺走并将其放入自动垃圾回收系统的计算机语言都有一个致命的缺陷:程序员可以很容易地阻止垃圾回收器工作。 任何继续拥有引用的对象都不能被垃圾回收,因此无法释放回系统内存。
不严谨的程序员不释放他们的引用会导致内存泄漏。 在具有许多对象的系统中(Java 程序中的几乎所有东西都是对象),一些小的泄漏可能会很快导致内存不足错误。 这些内存泄漏很难找到。 有时它们存在于你自己在处理的代码中,但通常它们存在于你的代码所依赖的库中。 如果无法访问库代码,则 bug 是无法修复的,即使可以访问源代码,谁又愿意花时间修复其他人代码中的内存泄漏呢? 我当然不愿意。 摩尔定律通常可以保护傻瓜和小孩免受这些问题的困扰,因为虽然频率缩放已经停止,但内存密度仍在继续增加。 当你的老板尖叫着要发布你正在处理的任何东西的下一个版本时,为什么还要费心去查找代码中的那个小泄漏呢? “系统保持运行了一整天,发布它吧!”
第二个 bug 更为有害。 你没有问的一个问题是,“为什么我们的系统中有垃圾回收器?” 我们有垃圾回收器的原因是,在过去的某个时候,有人——嗯,实际上是一群人——想要补救另一个问题:无法管理自己内存的程序员。 C++,另一种面向对象的语言,在程序执行时也有很多对象在浮动。 在 C++ 中,我们都知道,对象必须使用 new 和 delete 创建或销毁。 如果它们没有被销毁,那么我们就会发生内存泄漏。 程序员不仅必须管理对象,而且在 C++ 中,程序员还可以直接访问对象底层的内存,这导致调皮的程序员触摸他们不应该触摸的东西。 C++ 运行时并没有真正说,“坏触摸,叫大人来,”但这正是段错误真正意味着的。 根据你的观点,垃圾回收的推广要么是为了将程序员从手动管理内存的繁琐工作中解放出来,要么是为了防止他们做不好的事情。
问题是我们用一组问题换取了另一组问题。 在垃圾回收之前,我们会忘记删除一个对象,或者错误地双重删除它; 而在垃圾回收之后,我们必须管理我们对对象的引用,说实话,这与忘记删除对象是完全相同的问题。 我们用指针换取了引用,但并没有因此变得更聪明。
KV 的长期读者知道,灵丹妙药永远不起作用,而且必须非常小心地保护程序员免受他们自己的伤害。 创建垃圾回收语言的副作用是,虚拟机管理内存的开销对于许多工作负载来说太高了。 性能损失导致人们构建了大量的 Java 库,这些库不使用垃圾回收,并且其中的对象必须手动管理,就像使用 C++ 等语言一样。 当你的一个关键功能具有如此高的开销,以至于你自己的用户创建了巨大的框架来避免该功能时,肯定出了大问题。
现在的状况是这样的:对于 C++(或 C)程序,与在具有大量 RAM 的现代系统上看到内存不足错误相比,你更有可能看到段错误和内存粉碎 bug。 如果你正在运行用 Java 编写的东西,那么你最好拿出钱来购买你可以管理的所有内存条,因为你将需要它们。
KV
亲爱的 KV,
我忍不住注意到,很多大型系统都称自己为“操作系统”,但它们实际上与操作系统没有太多相似之处。 操作系统的定义是否已经改变到任何大型软件都可以称自己为操作系统的程度?
OS 还是非 OS
亲爱的 OS,
当然,我对操作系统的定义并没有改变到任何大型软件都可以称自己为操作系统的程度,但我也发现了这种趋势。 一个古老的笑话是,每个程序的大小都会增长,直到它可以用来阅读电子邮件,如果你相信维基百科,这归因于 Jamie Zawinski,基于 Greg Kuperberg 早期的笑话,“麻省理工学院开发的每个程序都会扩展,直到它可以阅读邮件。” 现在,似乎邮件还不够。 每个大型程序都会扩展,直到在其名称后附加“OS”。
操作系统是一个程序,用于有效地访问底层的硬件,希望以可移植的方式进行,尽管这不是一个严格的要求。 该软件的目的是为程序员提供一组一致的 API,这样他们就不需要在每次想在新计算机型号上运行程序时都重写底层代码。 这可能不是牛津词典对 OS 的定义,但由于它最近将 自拍 添加到词典中,我开始对他们的输出质量感到有些失望。
我认为程序员倾向于将他们更大的创作标记为操作系统,这来自于获得吹嘘权利的需求。 程序员从不停歇地将他们的代码与同行的代码进行比较。 即使在实际的操作系统项目中也可以看到这一点。 每个人似乎都想(重新)编写调度器。 为什么? 因为对于许多程序员来说,它是系统中最重要的代码,如果他们做得很好,并且调度器运行得非常好,他们就会让他们的同行羡慕不已。 不要介意调度器真的应该非常小,而且非常非常简单,但这并不是重点。 重点是重新编写它所获得的吹嘘权利,通常是第 n 次。
这一切都不是要贬低那些辛勤工作,努力制作出优雅的复杂代码,让我们的生活更美好的程序员或程序员团队。 但是,如果你仔细观察,你会发现这些代码的命名是恰当的,它们不需要附加 OS 来使它们看起来更大。
KV
喜欢它,讨厌它? 让我们知道
Kode Vicious,在凡人眼中是 George V. Neville-Neil,为了乐趣和利润而从事网络和操作系统代码的工作。 他还教授与编程相关的各种主题的课程。 他的兴趣领域是代码探险、操作系统和重写你的糟糕代码(好吧,也许不是最后一个)。 他在马萨诸塞州波士顿的东北大学获得了计算机科学学士学位,并且是 、Usenix 协会和 IEEE 的成员。 他是一位狂热的自行车爱好者和旅行者,目前居住在纽约市。
© 2013 1542-7730/13/0900 $10.00
最初发表于 Queue 第 11 卷,第 10 期—
在 数字图书馆 中评论这篇文章
Catherine Hayes, David Malone - 质疑评估非加密哈希函数的标准
尽管加密和非加密哈希函数无处不在,但在它们的设计方式上似乎存在差距。 加密哈希存在许多由各种安全需求驱动的标准,但在非加密方面,存在一定程度的民间传说,尽管哈希函数历史悠久,但尚未得到充分探索。 虽然针对真实世界数据集的均匀分布非常有意义,但当面对具有特定模式的数据集时,这可能是一个挑战。
Nicole Forsgren, Eirini Kalliamvakou, Abi Noda, Michaela Greiler, Brian Houck, Margaret-Anne Storey - DevEx 在行动
随着领导者寻求在财政紧缩和人工智能等变革性技术的背景下优化软件交付,DevEx(开发者体验)在许多软件组织中越来越受到关注。 直观地看,技术领导者普遍认为,良好的开发者体验能够实现更有效的软件交付和开发者幸福感。 然而,在许多组织中,旨在改进 DevEx 的拟议举措和投资难以获得支持,因为业务利益相关者质疑改进的价值主张。
João Varajão, António Trigo, Miguel Almeida - 低代码开发效率
本文旨在通过展示使用基于代码、低代码和极端低代码技术进行的实验室实验结果,研究生产力差异,从而为该主题提供新的见解。 低代码技术已清楚地显示出更高的生产力水平,为低代码在短期/中期内主导软件开发主流提供了强有力的论据。 本文报告了程序和协议、结果、局限性以及未来研究的机会。
Ivar Jacobson, Alistair Cockburn - 用例至关重要
虽然软件行业是一个快节奏且令人兴奋的世界,其中不断开发新的工具、技术和技巧来服务于商业和社会,但它也很健忘。 在其快速前进的过程中,它容易受到时尚潮流的影响,并且可能会忘记或忽略针对其面临的一些永恒问题的成熟解决方案。 用例于 1986 年首次引入,并在后期普及,是这些成熟的解决方案之一。