第十天笔记

内存泄漏

1. Java垃圾回收机制

1.1 什么是垃圾回收
  • 垃圾回收(GC)是由Java虚拟机(JVM)垃圾回收器提供的一种内存回收机制。
  • 当内存空间或内存占用过高时,系统会回收那些没有引用的对象。
JVM内存模型
  • 运行时数据区域:包括方法区、堆、栈、本地方法栈和程序计数器等。
  • 堆内存:
    • 新生代(Young Generation):分为Eden区和两个Survivor区(S0、S1)。
    • 老年代(Old Generation)。
  • 方法区MetaSpace):存储类元数据、方法信息等。

1.2 判断对象是否是垃圾的算法

1.2.1 引用计数算法
  • 对象被创建后,系统为其初始化引用计数器。
  • 每当对象被引用时,计数器加1,引用失效时,计数器减1。
  • 当计数器为0时,对象不再被引用,可以进行回收。
  • 优点:判断简单,效率高。
  • 缺点:无法避免循环引用。
1.2.2 可达性分析法
  • 从GC Roots出发,逐步遍历到所有可达的对象。
  • 这些对象称为可达对象,不可达的对象则被标记为垃圾,需要回收。
GC Roots包括的对象:
  1. 虚拟机栈中引用的对象(栈帧中的本地变量表)。
  2. 方法区中类静态属性引用的对象。
  3. 方法区中常量引用的对象。
  4. 本地方法栈中JNINative方法)引用的对象。

Java中的对象引用

Java中的对象引用主要分为四种类型:

1. 强引用 (Strong Reference)

  • 定义: 例如 Object obj = new Object(),这是Java程序中最常见的引用类型。
  • 特点: 强引用是不可回收的资源,垃圾回收器不会回收它。当内存空间不足时,JVM宁愿抛出 OutOfMemoryError 错误,也不会回收强引用的对象。

2. 软引用 (Soft Reference)

  • 定义: 软引用是一种相对强引用有所弱化的引用。
  • 特点: 可以让对象避免一些垃圾收集。只有当JVM认为内存不足时,才会尝试回收软引用指向的对象。在抛出 OutOfMemoryError 之前,JVM会确保回收软引用的对象。软引用通常用于实现内存敏感的缓存,如果有足够内存,软引用对象会被保留。

3. 弱引用 (Weak Reference)

  • 定义: 弱引用的强度比软引用更弱。
  • 特点: 无论内存是否充足,当JVM进行垃圾回收时,都会回收被弱引用关联的对象。

4. 虚引用 (Phantom Reference)

  • 定义: 虚引用也称为幽灵引用或幻象引用,是最弱的一种引用关系。
  • 特点: 虚引用的存在不会对对象的生命周期构成影响,无法通过虚引用获得对象实例。唯一的目的是在对象被垃圾回收器回收时收到系统通知。

图示总结

  • 强引用: 只有在没有空闲内存时才会被回收。
  • 软引用: 在内存不足时会被回收。
  • 弱引用: 在垃圾回收检测时立即回收。
  • 虚引用: 不会直接影响对象生命周期,但能在对象被回收时收到通知。

这个图示展示了不同引用类型如何与垃圾回收器交互,以及在垃圾回收后的结果。

初识ANR

主线程执行耗时操作

当主线程执行耗时操作(如大量计算、循环、递归、IO操作等)会导致ANR。

示例代码:

mBind.textView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        while (true) {
            Log.i("TAG", "主线程执行耗时操作");
            try {
                // 执行耗时操作
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
});

死锁

当对象锁被其他线程持有,主线程长时间无法获取当前对象锁,会导致ANR。

示例代码:

public class MainThreadAnrActivity extends BaseActivity<ActivityHandlerBinding> {
    private final Object object = new Object();
    private final String TAG = MainThreadAnrActivity.class.getSimpleName();
    private boolean taskComplete = false;

    @Override
    protected void bindListener() {
        super.bindListener();
        mBind.textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 需要使用子线程执行的结果
                synchronized (object) {
                    Log.i(TAG, "死锁导致ANR " + taskComplete);
                }
            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object) {
                    try {
                        Thread.sleep(30 * 1000);
                        taskComplete = true;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

解决方法

  1. 使用ReentrantLock代替synchronized,同时tryLock()增加最大等待时间,超过最大等待时间主动释放锁,避免出现ANR。

示例代码:

ReentrantLock lock = new ReentrantLock();
lock.tryLock(3000, TimeUnit.MICROSECONDS);

image-20240715083201068

image-20240715084113793

android长生命周期:applicationservice content provider

image-20240715085520414

image-20240715094056874

image-20240715094326344

image-20240715094307652

image-20240715094621823

image-20240715094739966

image-20240715094754660

image-20240715094821284

image-20240715094907423

image-20240715101802654

image-20240715102028158

image-20240715102219786

image-20240715102359671

image-20240715102417686

image-20240715134402970

image-20240715134417291

image-20240715134747200

image-20240715160811536

image-20240715134853218

image-20240715161430073

image-20240715140819084

image-20240715140753591

image-20240715135402440

image-20240715135608017

image-20240715135706092

image-20240715135751337

image-20240715135905966

image-20240715135916678

image-20240715140205655

image-20240715140336310

image-20240715140452449

image-20240715140628406

image-20240715161746937

image-20240715161948527

image-20240715161956264

image-20240715162232386

image-20240715162337388

image-20240715162354936

image-20240715164936107

image-20240715164939280

image-20240715164954918

image-20240715165014067

作业

image-20240715165146498