调用 finish() 不会清除对 Activity 的内存引用

2023-12-05

在我的应用程序的简化版本中,我有两个活动 A 和 B。活动 A 启动 B,并在完成一些工作后 B 调用 finish()。在大多数设备(运行 4.2 的 Galaxy Nexus、运行 4.0.4 的 Droid 4 和运行 2.3.4 的 Droid 2)上使用内存分析器工具都没有显示活动 B 的痕迹,这正是我所期望的。

但在运行 4.1.1 的 Samsung S3 上,由于到以下 GC 根的路径(排除弱/软引用),MAT 显示活动 B 对象仍然存在:

Class Name                                                        | Shallow Heap | Retained Heap
-------------------------------------------------------------------------------------------------
com.myCo.myApp.ActivityB  @ 0x42720818                            |          264 |         3,280
|- <Java Local> java.lang.Thread @ 0x4271cf60  Thread-21941 Thread|           80 |        52,264
|- mOuterContext android.app.ContextImpl @ 0x426adf68             |          104 |           784
    |  '- mContext android.media.AudioManager @ 0x428e49a0        |           48 |           152
-------------------------------------------------------------------------------------------------

每次我启动和停止活动 B 时,MAT 都会显示活动 B 内存占用的另一个实例。我打开/关闭活动 B 的次数越多,logcat 中报告的内存占用量就越大。通过 MAT 强制执行 GC 不会删除对活动 B 内存的引用。

我有三个问题。

  1. 为什么不同设备上的内存/GC 行为不同?

  2. 在 S3 上,操作系统最终会回来并 GC 搁浅的 Activity B 对象吗(换句话说,我不应该担心它吗,因为 Android 会在崩溃之前清理它)?

  3. 如果没有,Thread 和 AudioManager 引用从何而来,我将如何清除它们?

感谢所有经验丰富的“泄漏猎人”!


更新:为了查看活动 B 留下的“搁浅”内存实际上是否是一个问题,我在活动 A 和 B 之间创建了一个循环:

--- A calls startActivityForResult() on B
--- B calls finish()
--- onActivityResult() in A calls B again, etc...

我让它飞行了大约 15k 次迭代,程序没有崩溃。因此,即使此手机和操作系统版本(Samsung S3,4.1.1)上的 JVM 在内存中留下了对类 B 的引用,即使在 Activity B 调用 finish() 之后,似乎也有某种稍后的清理,因为在测试过程中,对 B 类的引用数量并没有单调增加。

事实上,我在测试期间生成了多个堆转储,并且从未看到过超过大约 100 个 B 类实例——而不是我期望在没有其他清理的情况下看到的 15k 个实例。 logcat 中的 GC 语句还显示内存使用量不断上升和下降,尽管活动 B 的调用量很大。

我的结论是,我不应该担心 finish() 调用后堆转储中是否存在 B 类引用,因为看来此手机/Android 版本上使用的 JVM 会进行某种延迟清理。

注意:这是我根据我运行的测试得出的推论,所以如果有人有不同的了解,请分享。谢谢!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调用 finish() 不会清除对 Activity 的内存引用 的相关文章

  • 在根项目“bin”中找不到任务“bintrayUpload”

    我遵循了将 AAR 文件发布到 JCenter 所需的每个步骤 然后使用 Maven Central 将其同步https github com danielemaddaluno gradle jcenter publish https gi
  • 如何在应用程序关闭时在 Android 通知中显示操作按钮?

    我有一个安卓应用程序 对于通知 我们必须显示一些操作按钮 当应用程序打开时 我们可以自由地构建通知并显示操作按钮 但是当应用程序关闭时 通知会在 Android 的通知托盘中收到 应用程序开发人员无法控制构建用户界面和操作按钮 我们现在如何
  • 在 Android 上使用 AT 命令与调制解调器对话

    我试图与三星 Galaxy s2 plus 和华为 p1 xl u9200 调制解调器发送 AT 命令 但无法得到任何结果 我使用 adb shell 发送命令并使用 logcat 查看日志 在三星 当我执行 cat 时 proc tty
  • 如何通过我的活动在 Android 中设置铃声?

    我正在尝试找到一种方法来通过 Android 活动中的代码设置新的默认铃声 我已经将铃声下载到bytearray 最后 我设法将默认铃声设置为我下载的铃声 下面不包含下载代码 仅包含将其设置为默认铃声所需的代码 File k new Fil
  • Android 中的列表(特别是 RecyclerView 和 CardView)如何工作

    请原谅我问这个问题 但我是 Android 开发新手 尽管我正在尝试了解developer android com 网站上的基础知识 但大多数示例 即使他们说它们是为 Android Studio 构建的 尚未设置为使用 Gradle 因此
  • 改造中的多个队列导致内存不足错误?

    我正在使用retrofit2 做我的项目 当我的呼叫失败时 我再次重复相同的呼叫 重复此 呼叫使我的应用程序强制关闭 当我查看日志时 我得到了错误日志 如下所示 我觉得这是由于同一呼叫的多次排队造成的 所以我在排队之前就这样做了 我打电话给
  • 覆盖 Android 中的电源按钮

    我正在开发一个应用程序 其中我需要在按下电源按钮时执行一个操作 但不幸的是我无法处理按下电源按钮时的操作 我尝试使用 onKeyDown 和dispatchKeyEvent 方法 但似乎没有任何效果 任何人都可以建议我解决这个问题的任何其他
  • 退出设备上的 system.img

    我正在为我们部署给客户的设备 LG p509 Optimus 1 开发自动应用程序更新解决方案 我们可以控制这些设备 并且目前在它们上安装自定义内核 但不是完整的自定义 ROM 由于我们试图在设备上自动更新我们的应用程序 因此我们需要由我们
  • 如果使用grifika的ContinualCaptureActivity中的预览方式,相机预览的视野会更小

    我们知道 当相机预览比例设置为时 在相同距离下我们会得到更大的预览视野4 3代替16 9 具体如下 Android Camera API 奇怪的缩放效果 https stackoverflow com questions 20664628
  • ADB TCPIP 连接问题

    我有两台 Galaxy S3 其中一个已扎根 另一个则未扎根 因此 当我尝试通过本地网络连接它们时 计算机可以看到已root的计算机 但是正常的就卡在tcpip这一步了 所以 我写 adb tcpip 5555 It says restar
  • 从ListView中隐藏行而不占用空间

    我有一个带有关联 ArrayAdapter 的 ListView 它在多个活动中显示其内容 不幸的是 现在有必要 我的 ListView 在其中一项设置中不显示其所有元素 而仅显示 属性 未设置为 true 的元素 我想避免使用两个具有不同
  • ExpandableListview OnGroupClickListener 未触发

    我正在关注这个 以编程方式折叠 ExpandableListView 中的组 https stackoverflow com questions 4314777 programmatically collapse a group in ex
  • Android上如何获取ImageView的Drawable的矩形?

    我想要获取将包裹 ImageView 的 Drawable 的矩形对象 而不是包裹 ImageView 的矩形 我将使用该矩形在 Drawable 周围绘制一些奇特的矩形 我怎样才能得到那个矩形 Rect rect new Rect Ima
  • Android 中 localTime 和 localDate 的替代类有哪些? [复制]

    这个问题在这里已经有答案了 我想使用从 android API 获得的长值 该值将日期返回为长值 表示为自纪元以来的毫秒数 我需要使用像 isBefore plusDays isAfter 这样的方法 Cursor managedCurso
  • 如何使用 SharedPreferences 保存多个值?

    我正在开发一个字典应用程序 在我的应用程序中 我假设用户想要保存最喜欢的单词 我决定使用共享首选项保存这些值 我知道 SQLite 和文件更好 但我坚持使用 SharedPreferences 所以继续使用它 下面是我的代码 Overrid
  • 如何将 Android 添加到 Phonegap 平台版本 3

    经过大量挖掘 我相信这个问题 https stackoverflow com questions 18423444 phonegap 3 doesnt work with andriod studio与我没有添加任何用于构建phonegap
  • onTaskRemoved() 在华为和小米设备中没有被调用

    我一直在使用onTaskRemoved 服务中的方法 用于检测应用程序何时通过滑动从设备最近列表中删除 我执行一些日志记录和发生这种情况时需要执行的一些其他操作 它工作完美 然后我在运行Android 6 0的华为设备上检查了这个方法 该方
  • Unity c# 四元数:将 y 轴与 z 轴交换

    我需要旋转一个对象以相对于现实世界进行精确旋转 因此调用Input gyro attitude返回表示设备位置的四元数 另一方面 这迫使我根据这个四元数作为默认旋转来计算每个旋转 将某些对象设置为朝上的简单方法如下 Vector3 up I
  • Android 标记如何实现拖放?

    你好 我正在 Android 中开发 MapView 应用程序 我有三个标记 我希望稍后能够使用 Google Map API getlocation function 为了尝试一下 我想使用拖放功能移动标记 然后检查位置 任何人都可以通过
  • 检查应用程序是否在 Android Market 上可用

    给定 Android 应用程序 ID 包名称 如何以编程方式检查该应用程序是否在 Android Market 上可用 例如 com rovio angrybirds 可用 而 com random app ibuilt 不可用 我计划从

随机推荐

  • Mongodb:查询文档中的数组元素

    我有一个集合想要查询如下 返回所有文件 最多 2 条评论 例如 一个切片 0 1 或 2 条评论 所有评论的观看次数必须 gt 10 似乎我需要创建一个函数来单独评估每个文档 但尚不清楚这是如何完成的 特别是考虑到我想做一个切片并返回最多
  • Apache Dbutils 在更新 Sql 中更改列名称

    我在 Dbutils 方面遇到了一个奇怪的问题 我正在尝试运行参数化更新 sql 我提供了正确数量的参数 但是 dbutils 正在通过更改修改时间戳列名称来修改它 当时间戳列名是一个字母时 java sql SQLException 参数
  • 在Python中添加持续时间

    我想在Python中添加一系列的分割 时间以 00 08 30 291 等字符串开头 我似乎找不到使用 Python 对象或 API 来使其方便 优雅的正确方法 时间对象似乎不使用微秒 因此我使用 datetime 的 strptime 成
  • 通过名称或 ID 的一部分获取元素

    这是我的表单示例 仅输入我想要的内容 但还有很多其他内容
  • 谷歌云视觉OCR支持条码读取吗?

    我正在构建一个利用谷歌云平台的 OCR 服务的应用程序 我仍在进行中 只是想知道该服务是否也可以检测条形码并对其进行解码 Thanks 不可以 要求用户有网络连接只是为了读取条形码会太过分 而且速度太慢 查看谷歌移动视觉API相反 它在设备
  • 使用asynctask调用android中的函数

    如下代码所示 我有一个名为record 我想用 asynctask 调用这个函数 但我不知道如何使用 asynctask 记录函数需要很长时间才能完成一些任务 所以我需要使用 asynctask public class Record ex
  • iOS MapKit 显示一定距离内最近的注释

    目前我正在为 iPhone iPad 开发基于位置的应用程序 我的 MapKit 中有几个注释 我想要做的是跟踪用户的位置并显示 3km 内的注释 有人可以给我一个开始吗 抱歉回复延迟了 这个问题刚刚从我的视线中消失了 我假设你有一个方法返
  • 如何从代码中获取iPhone的型号。 (例如 MC143C)

    我需要从代码中获取 iPhone 型号 我可以从我的 iPhone 中看到型号 MC143C 但是当我使用代码检索它时 它返回 iPhone 这是我用来获取型号的代码 NSLog model UIDevice currentDevice m
  • WCF 错误:客户端和服务绑定可能不匹配?

    让我们看看服务器配置和客户端配置 然后帮我找出这些配置之间的区别 客户端配置
  • 如何模仿模板变量声明

    我有一个基本类型Item
  • 从包含 标签的 Java 字符串中提取 url [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我想提取以下字符串 http www 01net com images article mea 150 100 790233 jpg 该字符串是以下 Java 字符串中第一个元素标记
  • 如何在网络表单中包含部分视图

    我正在编程的一些网站同时使用 ASP NET MVC 和 WebForms 我有一个部分视图 我想将其包含在网络表单中 部分视图有一些必须在服务器中处理的代码 因此使用 Response WriteFile 不起作用 它应该在禁用 Java
  • Django 动态 urlpatterns

    我正在构建一个简单的网络应用程序Django 我的用户被分为多个组 例如Group A Group B etc 我想做的是动态更新urlpatterns列出在urls py这样我就可以拥有相同 url 端点上的不同视图 例如 我想做这样的事
  • 动态调整弹出窗口大小时防止动画

    所以我自己意识到了这一点 并找到了这个答案来证实 防止 contentSizeForViewInPopover 产生动画效果 基本上我处于类似的情况 我想动态调整弹出窗口的大小 具体取决于我必须显示的数据量 我还得到了弹出视图移动到位的动画
  • 如何交替交换大写和小写?

    我正在编写一个程序 可以将大写字母转换为小写字母 也可以将小写字母转换为大写字母 这里有些例子 abcde gt aBcDe ABCDE gt aBcDe abCdE gt aBcDe 我知道如何用 c 语言编写它 但不知道如何用 shel
  • Java 节流

    我如何使用组合ScheduledThreadPoolExecutor ScheduledFuture and ExecutorCompletionService节流Callable接受可变参数的命令 收到回复后Callable命令 我需要创
  • Firebase 到自定义 Java 对象

    users mchen friends brinchen true name Mary Chen widgets one true three true brinchen hmadi 如何为上面的示例编写自定义对象类 Firebase 中的
  • 有什么方法可以使用 Facebook 的 PHP SDK 或 API 取消好友关系或删除好友吗?

    我希望能够对用户进行身份验证 列出他们的所有朋友 并让他们能够取消好友 删除其中一些朋友 而无需通过 Facebook com 网站上的流程 这可以通过 API 实现吗 没有可用于以编程方式添加或删除好友的 API 可用的是您的应用可用来帮
  • ApplicationPoolIdentity无法访问网络资源

    我的设置 W2K8 R2 IIS7 5 x64 位服务器 但应用程序池以 32 位运行 我们有一个在 ApplicationPoolIdentity 下运行的 net 4 0 Web 应用程序 它启用了 Windows 身份验证 Web 应
  • 调用 finish() 不会清除对 Activity 的内存引用

    在我的应用程序的简化版本中 我有两个活动 A 和 B 活动 A 启动 B 并在完成一些工作后 B 调用 finish 在大多数设备 运行 4 2 的 Galaxy Nexus 运行 4 0 4 的 Droid 4 和运行 2 3 4 的 D