ash*_*exm 52 java memory performance memory-management
帮助我解决与同事之间的争议:在Java中将变量或集合设置为null有助于垃圾收集并减少内存使用吗?如果我有一个长时间运行的程序,并且可以迭代地调用每个函数(可能数千次):在将值返回到父函数之前将其中的所有变量设置为null有助于减少堆大小/内存使用量吗?
sbl*_*ndy 59
这是旧表现的绝杀.这在1.0天内确实如此,但编译器和JVM已得到改进,以消除需求(如果有的话).如果您感兴趣,这篇优秀的IBM文章会详细介绍:Java理论与实践:垃圾收集和性能
来自文章:
有一种情况是使用显式归零不仅有用,而且实际上是必需的,并且这是对对象的引用范围比程序规范使用或认为有效的范围更广.这包括诸如使用静态或实例字段来存储对临时缓冲区的引用而不是本地变量的情况,或者使用数组来存储可以由运行时保持可访问而不是由程序的隐含语义可访问的引用.
翻译:"显式null"不再需要的持久对象.(如果你愿意."几乎要求"声明过于强烈?)
Java VM Spec
12.6.1实现终结每个对象都可以用两个属性来表征:它可以是可达的,终结器可达的,或者是不可达的,它也可以是未终结的,可终结的或最终的.
可到达对象是可以从任何活动线程的任何潜在继续计算中访问的任何对象.可以设计优化程序的转换,以减少可达到的对象的数量,使其少于可以被认为可达的对象的数量.例如,编译器或代码生成器可以选择设置将不再用于null的变量或参数,以使得此类对象的存储可能更快地被回收.
讨论
如果对象字段中的值存储在寄存器中,则会出现另一个示例.然后程序可以访问寄存器而不是对象,并且永远不会再次访问对象.这意味着该对象是垃圾.
如果对象可以参与任何潜在的持续计算,则该对象是可达的.因此,如果您的代码引用了局部变量,并且没有其他内容引用它,那么您可以通过将其设置为null来使对象收集.这可能会给出一个空指针异常,或者改变程序的行为,或者如果它既没有,那么你首先不需要变量.
如果要将字段或数组元素归零,那么对于某些应用程序来说这可能是有意义的,并且它将使内存更快地被回收.一旦case正在创建一个大型数组来替换类中某个字段引用的现有数组 - 如果创建了替换之前为空的字段,那么它可以减轻对内存的压力.
Java的另一个有趣特性是范围不会出现在类文件中,因此范围与可达性无关; 这两个方法创建相同的字节码,因此VM根本看不到所创建对象的范围:
static void withBlock () {
int x = 1;
{
Object a = new Object();
}
System.out.println(x+1);
}
static void withoutBlock () {
int x = 1;
Object a = new Object();
System.out.println(x+1);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
16464 次 |
最近记录: |