Android 内存泄漏和垃圾回收
Android Memory Leak and Garbage Collection
我有一个片段保持对父 activity 的引用。在 onCreateView 方法上,我通过将静态列表传递给适配器来初始化适配器。由于列表是 "static",是否意味着 Activity、Fragment 和 Adapter 永远不会被垃圾回收?
这是我的代码 -
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 永远不会被垃圾收集?此代码是否表示内存泄漏?
看来你的View如果满足指定的Fragment生命周期还是会被垃圾回收的。
至于静态的CConstantVariables,它将保留在内存中,直到您的应用程序结束。
请参考Static member views in activity - Android and Using static variables in Android
静态词通常意味着您的 数据仍在内存中的某个特定位置,并且当您的应用 运行 时,该内存位置不会改变。让我们更进一步,让静态值在设备 RAM 上分配一个特定位置,一旦定位变量启动,您可以随时从任何 activity 访问该位置。因此,只要您的应用程序运行,静态变量一旦保存就可能永远不会作为垃圾收集,并且堆将随着静态变量使用的增加而不断增加。如果您想删除其存储的值,您真正可以做的只是 设置变量 null
。 (不是位置)
我通常做的是回收它们。这不是一个可回收的代码,但我实际上是指创建大量静态变量,而不是创建一些(在我自己的应用程序中)并根据需要不断更改它们的值,从而控制无用的内存扩展。 (像我们处理塑料或任何金属一样回收)
是的,静态变量一旦分配可能会造成内存泄漏,如果 未设置为 null
可能会永久提供内存中的某个位置,直到您的应用程序结束。如果存储的值更大,例如位图,您可以清楚地观察到静态变量和普通变量之间的区别。
结论:尽量避免静态,直到除了使用静态之外没有其他选择。如果你确实使用然后继续清理存储的内存,你不能从 RAM 中删除位置但可以将值设置为 null
.
注意:与静态变量一起使用的函数将被正常垃圾收集,如果它不是静态的,就像列表视图的适配器一样。 (在您的情况下,您收集了适配器垃圾)。
希望我能解释清楚,如果有任何问题或任何更正,请发表评论。
干杯!
GC 将收集所有未从 GC-root 对象引用的对象。 GC-root 对象通常是:
- 所有 运行 个线程
- 所有静态字段
在您的示例中:CConstantVariables.listMyContestData
是静态的,因此是内存泄漏的潜在来源。您必须控制此列表的内容:
- 确保此列表不包含您不再需要的对象
- 确保该列表中的对象不包含对您不再需要的对象的引用。
在适配器中使用静态列表不会阻止适配器被垃圾收集(一旦不再有从 GC-root 对象 到适配器的引用)。
我向您推荐 Android 中关于跟踪内存泄漏的精彩演讲:https://www.youtube.com/watch?v=_CruQY55HOk
我有一个片段保持对父 activity 的引用。在 onCreateView 方法上,我通过将静态列表传递给适配器来初始化适配器。由于列表是 "static",是否意味着 Activity、Fragment 和 Adapter 永远不会被垃圾回收?
这是我的代码 -
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 永远不会被垃圾收集?此代码是否表示内存泄漏?
看来你的View如果满足指定的Fragment生命周期还是会被垃圾回收的。 至于静态的CConstantVariables,它将保留在内存中,直到您的应用程序结束。
请参考Static member views in activity - Android and Using static variables in Android
静态词通常意味着您的 数据仍在内存中的某个特定位置,并且当您的应用 运行 时,该内存位置不会改变。让我们更进一步,让静态值在设备 RAM 上分配一个特定位置,一旦定位变量启动,您可以随时从任何 activity 访问该位置。因此,只要您的应用程序运行,静态变量一旦保存就可能永远不会作为垃圾收集,并且堆将随着静态变量使用的增加而不断增加。如果您想删除其存储的值,您真正可以做的只是 设置变量 null
。 (不是位置)
我通常做的是回收它们。这不是一个可回收的代码,但我实际上是指创建大量静态变量,而不是创建一些(在我自己的应用程序中)并根据需要不断更改它们的值,从而控制无用的内存扩展。 (像我们处理塑料或任何金属一样回收)
是的,静态变量一旦分配可能会造成内存泄漏,如果 未设置为 null
可能会永久提供内存中的某个位置,直到您的应用程序结束。如果存储的值更大,例如位图,您可以清楚地观察到静态变量和普通变量之间的区别。
结论:尽量避免静态,直到除了使用静态之外没有其他选择。如果你确实使用然后继续清理存储的内存,你不能从 RAM 中删除位置但可以将值设置为 null
.
注意:与静态变量一起使用的函数将被正常垃圾收集,如果它不是静态的,就像列表视图的适配器一样。 (在您的情况下,您收集了适配器垃圾)。
希望我能解释清楚,如果有任何问题或任何更正,请发表评论。
干杯!
GC 将收集所有未从 GC-root 对象引用的对象。 GC-root 对象通常是:
- 所有 运行 个线程
- 所有静态字段
在您的示例中:CConstantVariables.listMyContestData
是静态的,因此是内存泄漏的潜在来源。您必须控制此列表的内容:
- 确保此列表不包含您不再需要的对象
- 确保该列表中的对象不包含对您不再需要的对象的引用。
在适配器中使用静态列表不会阻止适配器被垃圾收集(一旦不再有从 GC-root 对象 到适配器的引用)。
我向您推荐 Android 中关于跟踪内存泄漏的精彩演讲:https://www.youtube.com/watch?v=_CruQY55HOk