Android内存泄漏和垃圾收集

时间:2015-07-26 08:47:09

标签: android performance android-activity memory-leaks garbage-collection

我有一个片段,它继续引用父活动。在onCreateView方法上,我通过将静态列表传递给适配器来初始化适配器。由于列表是“静态的”,它是否意味着活动,片段和适配器永远不会被垃圾收集?

这是我的代码 -

public class MyFragment extends Fragment 
{
RecyclerView rvMyContestLists;
MyContestListAdapter adapter = null;
Activity activity;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
        // CConstantVariables.listMyContestData is static
        adapter = new MyContestListAdapter(activity, CConstantVariables.listMyContestData);
        rvMyContestLists.setAdapter(adapter);
        rvMyContestLists.setLayoutManager(new LinearLayoutManager(getActivity()));
 }
 }

使用“static”变量CConstantVariables.listMyContestData作为适配器的列表数据是否意味着Activity永远不会被垃圾收集?此代码是否表示内存泄漏?

3 个答案:

答案 0 :(得分:1)

GC将收集未从 GC-root 对象引用的所有对象。 GC-root 对象通常是:

  • 所有正在运行的主题
  • 所有静态字段

在您的示例中:CConstantVariables.listMyContestData是静态的,因此是潜在的内存泄漏源。您必须控制此列表的内容:

  • 确保此列表不包含您不再需要的对象
  • 确保该列表中的对象不包含对您不再需要的对象的引用。

在适配器中使用静态列表不会阻止适配器被垃圾回收(一旦没有更多来自 GC-root对象的引用到适配器)。

我建议您在Android中跟踪内存泄漏这个非常好的讨论:https://www.youtube.com/watch?v=_CruQY55HOk

答案 1 :(得分:0)

如果符合Fragment的指定生命周期,您的View似乎仍会被垃圾回收。 至于静态CConstantVariables,它将保留在内存中,直到你的应用程序结束。

请参阅Static member views in activity - AndroidUsing static variables in Android

答案 2 :(得分:0)

静态字通常表示您的数据仍在内存中的某个特定位置,并且在您的应用运行时内存位置不会发生变化。让我们更进一步,让静态值在设备RAM上分配一个特定位置,并且一旦启动了定位变量,您就可以随时从任何活动访问该位置。因此,只要您的应用程序运行,一旦保存的静态变量可能永远不会被收集为垃圾,并且随着不断增加的静态变量的使用,堆将继续增加。如果要删除其存储的值,您可以真正做的只是设置变量null 。 (不是位置)

我通常做的就是回收它们。这不是一个回收的代码,但实际上我的意思是创建大量的静态变量,我创建很少(在我自己的应用程序中)并根据需要不断更改其值,从而控制无用的内存扩展。 (同样地回收,因为我们做塑料或任何金属)

是的,静态变量可能会在分配后产生内存泄漏,如果未设置为null ,则可能会永久性地在内存中提供某个位置,直到您的应用结束。如果存储值较大(如位图),则可以清楚地观察到静态变量和普通变量之间的差异。

结论:尽量避免使用静力学,直到除了使用静态之外没有其他任何选择。如果您确实使用然后继续清理存储的内存,则无法从RAM中删除位置,但可以将值设置为null

注意:与静态变量一起使用的函数将被正常垃圾收集,如果它不是静态的,则与listview的适配器一样。 (在您的情况下,您收集了适配器垃圾)。

希望我能够解释得很好,或者评论是否有任何问题或任何更正。

干杯!