概述
最近在剖析一个内存占用问题,就经过 AS 的 Memory Profile
(卡是真的卡)去查看了一下内存状况,看到了两个 Size,官方解说:
- Shallow Size:
Total amount of Java memory used by this object type (in bytes); Size of this instance in Java memory.
- Retained Size:
Total size of memory being retained due to all instances of this class (in bytes); Size of memory that this instance dominates (as per the dominator tree).
类似下图(事务代码的剖析不方便贴出,随手写的 Demo 代码):
这篇文章咱们再温习一下 Shallow Size
和 Retained Size
这两个概念,在此之前需要对 Java GC
机制有必定的了解,曾经有记载过这块的内容,有爱好可以参考看看 Java 垃圾收回机制。需要注意一下 GC Root
,它们不会被 GC 收回,典型的 GC Root
就是静态变量,被 GC Root
直接 or 直接引证的对象也不会被收回。
Shallow Size
Shallow Size
是指实例本身占用的内存,不包含它引证的其他实例。即:
Shallow Size = 类界说 + 特点占用空间 + 位数对齐
在我的 64 位机器上测验如下:
-
类界说
:声明一个类本身所需的空间,固定为 8 个字节。类界说空间不会重复核算,即便类承继了其他类,也只算 8 个字节。界说了一个没有任何特点的类,查看其Shallow Size
巨细为 8 个字节。 -
特点占用空间
:所有特点所占空间之和,包含本身的和父类的所有特点。特点分为根本类型和引证,如 int 类型占 4 个字节,long 类型占 8 个字节,引证固定 (String, Reference) 占 4 个字节。 -
位数对齐
:使总空间为 8 的倍数。比方某个类以上两项共 21 字节,那么为了对齐,会取最接近 8 的倍数的值,即它的Shallow Size
是 24 个字节。与体系有关,有的不会对齐。
上面给出的截图,类结构如下,可以看出它就没有 位数对齐
这一项:
// Shallow Size = 28 = 8 + 4 + 8 + 4 + 4
// Retained Size = 36 = 28 + 8
data class Resource(
val int: Int,
val long: Long,
val string: String,
val reference: Res
)
// Shallow Size = 8
class Res()
Retained Size
Retained Size
是指某个实例被收回时,可以一起被收回的实例的 Shallow Size
之和。
因而在进行内存剖析时,咱们需要要点关注 Retained Size
较大的实例;另外也可以经过 Retained Size
判断出某个实例内部使用的实例是否被其他实例引证,比方说假如某个实例的 Retained Size
比较小,Shallow Size
比较大,说明它内部使用的某个实例还在其他地方被引证了(比方说对 Bitmap 实例而言,假如它的 Retained Size
很小,可以说明它内部的 byte 数组被另外的 Bitmap 实例复用了)。
举个栗子
现在有几个实例的引证关系如下图,假设每个实例的 Shallow Size
都为 X:
别离考虑收回这四个实例后,能开释的空间,即 Retained Size
巨细,咱们简单把某个实例 A 的 Retained Size
记作 R(A),Shallow Size
记作 S(A)。
- 移除 D 实例:D 没有引证任何实例,因而只会开释本身的
Shallow Size
,即R(D) = S(D) = X
。 - 移除 C 实例:移除 C 后,因为它引证了 D,且 D 没有被其他实例引证,因而 D 也会被一起收回,即
R(C) = S(C) + S(D) = 2X
。 - 移除 B 实例:移除 B 后,因为 B 和 A 实例都引证了 C 实例,所以移除 B 并不会让 C 实例被 GC 收回。即
R(B) = S(B) = X
。 - 移除 A 实例:B、C、D 实例被一起收回,即
R(A) = S(A) + S(B) + S(C) + S(D) = 4X
。
写在最终
在写这篇文章的时分翻了一些网上的博客,许多都是抄来抄去,或许说法各一,上面的数据经过了我自己的测验,发现 Shallow Size 具体巨细的核算这儿跟网上有些说法不太共同,有了解这块的同学可以谈论区沟通。
文中内容如有错误欢迎指出,共同进步!更新不易,觉得不错的留个赞再走哈~
Android视图体系:Android 视图体系相关的底层原理解析,看完定有收获。
Kotlin专栏:Kotlin 学习相关的博客,包含协程, Flow 等。
Android架构学习之路:架构不是一蹴而就的,期望咱们有一天的时分,可以从自己写的代码中找到架构的成就感,而不是干几票就跑路。作业太忙,更新比较慢,我们有爱好的话可以一起学习。
Android实战系列:记载实践开发中遇到和处理的一些问题。
Android优化系列:记载Android优化相关的文章,继续更新。