Shallow Size、Retained Size、Heap Size 和 Allocated

本文深入探讨了Java内存模型中的ShallowSize、RetainedSize和HeapSize概念,解析了对象在内存中的占用情况,以及垃圾回收机制如何影响内存管理。

Shallow Size:

Shallow size就是对象本身占用内存的大小,不包含其引用的对象。

  • 常规对象(非数组)的 Shallow size 由其成员变量的数量和类型决定。
  • 数组的shallow size有数组元素的类型(对象类型、基本类型)和数组长度决定。

在32位系统上,

  • 对象头占用 8 字节
  • int 占用4字节
  • 不管 成员变量(对象或数组)是否引用了其他对象(实例)或者赋值为null它始终占用4字节。

故此,对于String对象实例来说,它有三个 int 成员(34=12字节)、一个 char[] 成员(14=4字节)以及一个对象头(8字节),总共34 +14+8=24字节。
根据这一原则,对 String mStr=”rosen jiang”来说,实例 mStrshallow size也是24字节。(注意:上述String是jdk1.5的,代码如下:)

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];
 
    /** The offset is the first index of the storage that is used. */
    private final int offset;
 
    /** The count is the number of characters in the String. */
    private final int count;
 
    /** Cache the hash code for the string */
    private int hash; // Default to 0
	.....
	
	}

Retained Size:

对象的Retained Size = 对象本身的Shallow Size + 对象能直接或间接访问到的对象的Shallow Size
也就是说 Retained Size 就是该对象被 Gc 之后所能回收内存的总和。

为了更好地理解Retained Size,看下图对象的引用对象可以归纳为:该对象到其他对象有引用关系并且该引用对象到 Gc Root 节点是不可达的,所以有

  • 左图 obj1 的 Retained Size = obj1 + obj2 + obj4 的 Shallow size
  • 右图 obj1 的 Retained Size = obj1 + obj2 + obj4 +obj3 的 Shallow size

总之,Retained size是一个整体度量,能反映内存结构和对象图的依赖关系,还可以找到根节点。

图一

在进行垃圾回收时,如果实例对象到 Gc Root 是不可达的,那么该对象会被回收,如下图的 Object F 和 Object I

Heap Size:

堆的大小,当资源增加,当前堆的空间不够时,系统会增加堆的大小,若超过上限(如64M,阈值视平台而定)则会被杀掉 。

Allocated:

堆中已分配的大小,即 App 应用实际占用的内存大小,资源回收后,此项数据会变小。

建议:若单一操作反复进行,堆大小一直增加,则有内存泄露的隐患,可采用MAT进一步查看。


https://blog.youkuaiyun.com/yincheng886337/article/details/50517375
https://blog.youkuaiyun.com/kingzone_2008/article/details/9083327
http://www.blogjava.net/rosen/archive/2010/05/21/321575.html

使用 Android Studio Profiler 工具进行内存分析的方法如下: ### 启动 Memory Profiler 有 3 种启动方式: 1. 通过工具栏快速启动:确保设备/模拟器连接,选择目标应用进程(app)。点击 Android Studio 右侧工具栏 Profiler 图标(📊),选择 Memory 标签(红色内存图标)[^2]。 2. 通过菜单栏启动:View → Tool Windows → Profiler(或快捷键 Alt + 6),展开后选择内存模块[^2]。 3. 运行时实时监控:调试模式启动应用(Run 'app'),Profiler 会自动关联进程,显示实时内存曲线(包括 Heap SizeAllocated Objects、GC Events)[^2]。 ### 核心功能实战 #### 定位内存泄漏 - **检测 Activity 泄漏(销毁后实例未释放)**: - 在 Memory Profiler 中,点击 Dump Java Heap 按钮(🗑️,位于时间轴下方)。 - 在搜索框输入 Activity 类名(如 MainActivity),过滤实例列表。 - 关键判断:正常销毁后,实例数应为 0 或 1(可能因旋转屏幕等重建)。若实例数 ≥2 且持续存在,存在泄漏风险(点击实例查看引用链)[^2]。 #### 分析大对象(Shallow Size vs Retained Size) 可在 Memory Profiler 中查看对象的 Shallow Size Retained Size 来分析大对象,Shallow Size 是对象本身占用的内存大小,Retained Size 是对象被回收后能释放的内存大小。 ### 数据解读 Allocated 表示 Java 或 Kotlin 分配对象的数量(Android 8.0 以下时,仅统计 Memory Profiler 启动后,进程再分配的对象数量;8.0 以上时,由于系统内置了统计工具,Memory Profiler 可以得到整个 app 启动后分配对象的数量)[^3]。 ```java // 示例代码,假设这里是一个可能存在内存泄漏的 Activity public class MainActivity extends AppCompatActivity { private static SomeObject someObject; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); someObject = new SomeObject(); } } class SomeObject { // 类的具体实现 } ```
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值