我正在开发Android应用程序,我写的方法可能会被多次调用。在这个方法中,我正在更新用户界面。内存使用和性能对我来说很重要。我看到它的方式,我有2个选项来进行UI更改。
首先是每次都要制作新物品。这就是说:
public void myMethod(){
new View().makeVisible();
}
第二种是将对象声明为全局变量并在方法中引用它。这可能看起来像:
View myView = new View();
public void myMethod(){
myView.makeVisible();
}
显然,如果这种方法只召唤几次,那么任何差异都会很小。但是,如果我可能多次调用这个,并且有许多变量被调用/或以这种方式创建,那么第二种方式是否会提高性能?
答案 0 :(得分:3)
正如其他答案所示,重复使用相同的对象而不是为每个方法调用重复实例化一个新对象将减少内存占用并提高垃圾收集的性能。
但我实际上会首先考虑可维护性。是否重用相同的对象会使您的代码更复杂(并可能引入错误)?在编程时记住效率是件好事,但要避免过早优化,这会使项目复杂化并减缓开发。
如果性能和内存使用 是一个问题,那么是的,重用相同的View
会使您受益:
final View myView = new View(); //made final because it shouldn't be reassigned
如果你真的想获得资源,你甚至可以懒惰地加载对象 - 也就是说,只在需要时立即创建它。但是我会建议使用Guava的Suppliers.memoize(Supplier)
来处理这个问题,而不是手工编写这种行为:
final Supplier<View> myViewSupplier = Suppliers.memoize(new Supplier<View>() {
@Override
public View get() {
return new View();
}
});
...
public void myMethod() {
View myView = myViewSupplier.get(); //lazy-loads when first called
myView.makeVisible();
}
但这对于这种特殊情况来说可能是极端的。
答案 1 :(得分:1)
我认为这个决定不应该仅仅依靠效率来决定 - 而是根据哪个组合更好地代表你想要建模的领域。要问的问题是“哪个是我班级使用View的正确结构?”。
使用实例变量不是全局变量 - 它包含在声明它的对象的上下文中。尽管公共静态变量非常接近,但全局变量不应存在于OO中。
首先要确定的是你的“View”实例在逻辑上属于相对于使用它的类/方法的意图的位置。如果使用它的类是某种工厂,并且“myMethod”是工厂方法,则yes返回一个新实例。
如果“View”是您的类的逻辑字段,并以某种方式帮助捕获和增强其状态和行为,那么没有理由每次都创建一个新的。只需保持其状态,并使用现有对象。
从您的描述中,您似乎正在尝试维护和更新某种视图的状态。将其更改为所需状态并重新显示它是有意义的,而不是每次都创建一个新对象。从功能上看,这两种方法都适用于您的场景,我会采用第二种方法,避免创建不必要的对象。
答案 2 :(得分:0)
全局变量更有效。
创建新对象具有更多的内存占用,因为每次创建视图并替换旧视图时,旧视图都必须进行垃圾回收。使用全局变量重用相同的视图可以使系统保存创建新对象和收集旧对象的任务。
编辑: 全局变量只是对象的引用,而不是对象本身。
答案 3 :(得分:0)
好吧,当你让每个构造函数都创建一个新实例时,基本上你再次执行工作并不是绝对必要的。如果我在你的鞋子里,我将拥有全局变量选项,然后清除视图,并在可能的情况下重绘同一个对象。这可以防止重复内存释放和使用其他方法分配的可能性,因此,除非您认为清算特别昂贵 - 足以使其值得继续分配新视图,然后擦除它。
重用同一个对象的另一个动机是java虚拟机实现对垃圾收集的使用不同,因为一旦变量超出范围就无法访问 - 当释放对应于JVM的内存时总是一样。您可以发现,使用替代方案,您可以按顺序分配许多视图的实例,但在进程闲置一段时间之前不会全部解除分配,从而有效地使应用程序成为您不想要的内存耗尽。