【问题标题】:Good approach to avoid memory leaks避免内存泄漏的好方法
【发布时间】:2017-05-16 21:30:19
【问题描述】:

我正在用 Android 数据绑定试验 MVVM。我的代码如下:

public class ... extends Activity {    
        ...            
        private CommentViewModel viewModel;

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            binding = DataBindingUtil.setContentView(this, provideLayout());
            viewModel = new CommentViewModel(this);
            binding.setViewModel(viewModel);
        }

        @Override
        protected void onDestroy() {
            viewModel = null; //setting view model to null to avoid leaks
            super.onDestroy();
        }
}

我试图做的是在onDestroy() 中将我的ViewModel 设置为null,以避免任何可能的泄漏。

由于我的ViewModel 本身向另一个组件注册了一些callbacks 并使用context,如果其中一个回调未被删除并且上下文被传递到某处,则可能会泄漏,我决定将其设置为null。

但是我的同事发起了一个有趣的讨论,他说这是一种过时的做法,正如“有效的 Java”所暗示的那样,这就是你在 C++ 中的做法。他说一个好的方法是从 ViewModel 中删除所有回调,而不是将其设置为 null。比如:

public class ... extends Activity {    
        ...            
        private CommentViewModel viewModel;

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            ...//same as above
        }

        @Override
        protected void onDestroy() {
            viewModel.removeCallbacks(); //removing all callbacks from view model to avoid leaks
            super.onDestroy();
        }
}

现在两种方法都可以正常工作,但在第一种方法中,我非常确信不会发生泄漏。但结果,它看起来有些难看。第二种方法效果很好,但它迫使我考虑ViewModel 中可能发生的所有可能的泄漏。

这可能是一个普遍的问题:您认为哪种方法更好,为什么?

【问题讨论】:

    标签: java android mvvm memory-leaks garbage-collection


    【解决方案1】:

    一般来说,让 JVM 来完成它的工作。

    没有什么比这样的事情更烦人了

    System.gc()
    

    在大型应用的生产代码中。中间件工程师的工作是调优 JVM 以及如何管理内存——我真的是作为这些人说话的。在您的情况下,情况相同,开发 Android 的人最了解如何在其中管理 GC。如果它不会使任何东西更清晰/更容易理解,你不应该编写更多代码。

    另一方面

    有经验的程序员应该知道与框架相关的所有肮脏技巧(例如:stackoverflow.com/questions/13534030/can-a-scheduled-future-cause-a-memory-leak)以及如何不取消,不取消引用,不关闭等可能会导致内存泄漏。

    在您的情况下可能更重要的是,您可以想象会有相当复杂的回调(假设它们是循环的并且有数千个),并且使您的引用为 null 不会让任何事情变得更容易对于 GC,但删除回调会。

    【讨论】:

    • "将引用设为 null 不会让 GC 变得更容易,但删除回调会。" - 你能解释一下吗?我不明白。两者不是一回事吗?
    猜你喜欢
    • 2017-05-06
    • 1970-01-01
    • 2018-04-08
    • 2013-06-24
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    相关资源
    最近更新 更多