草庐IT

java - 与垃圾收集语言一起使用时,哪种代码的 CPU/内存效率更高?

coder 2024-03-14 原文

我有这两段虚拟代码(假设它们是用 Java 或 C# 编写的,所有变量都是本地的):

代码 1:

int a;
int b = 0;

for (int i = 1; i < 10 ; i++)
{
    a = 10;
    b += i;

    // a lot of more code that doesn't involve assigning new values to "a"
}

代码 2:

int b = 0;

for (int i = 1; i < 10 ; i++)
{
    int a = 10;
    b += i;

    // a lot of more code that doesn't involve assigning new values to "a"
}

乍一看,我会说这两个代码消耗相同数量的内存,但代码 1 的 CPU 效率更高,因为它只创建和分配变量 a 一次。 然后我读到垃圾收集器非常高效,以至于代码 2 的内存(和 CPU?)效率更高:将变量 a 保留在循环中使其属于 Gen0,所以它会是在变量 b 之前收集的垃圾。

因此,当与垃圾收集语言一起使用时,代码 2 的效率更高。我说得对吗?

最佳答案

几点:

  • int(和其他原语)从不在堆上分配。它们直接存在于线程堆栈上,“分配”和“释放”是指针的简单移动,并且发生一次(进入函数时,返回后立即发生),与范围无关。

  • 经常访问的基元通常存储在寄存器中以提高速度,同样,无论作用域如何。

  • 在您的情况下,a(可能还有 b,连同整个循环)将被“优化掉”,优化器足够聪明检测变量值发生变化但从未被读取的情况,并跳过冗余操作。或者,如果有代码实际查看 a,但不修改它,它可能会被优化器替换为常量值“10”,它将内联出现在任何地方a 被引用。

  • 新对象(例如,如果你做了类似 String a = new String("foo") 而不是 int 的操作)总是分配在年轻代, 并且只有在他们在一些小的 Collection 中幸存下来之后才会被转移到老年代。这意味着,在大多数情况下,当一个对象在函数内部分配,并且从不从外部引用时,无论其确切范围如何,它都永远不会进入老一代,除非你的堆结构迫切需要调整。

  • 正如评论中所指出的,有时 VM 可能会决定直接在老一代中分配一个大对象(这对 java 也是如此,而不仅仅是 .net),所以上面的观点只适用于大多数情况例,但不是总是。然而,对于这个问题,这没有任何区别,因为如果决定在老年代分配一个对象,无论如何它都是在不考虑其初始引用范围的情况下做出的。

从性能和内存的角度来看,您的两个代码段是相同的。但是从可读性的角度来看,在尽可能窄的范围内声明所有变量总是一个好主意。

关于java - 与垃圾收集语言一起使用时,哪种代码的 CPU/内存效率更高?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27865812/

有关java - 与垃圾收集语言一起使用时,哪种代码的 CPU/内存效率更高?的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  5. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  6. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  7. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  8. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  9. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  10. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

随机推荐