主页

JVM GC

前言

JVM 内存结构 中,我们说到,当 JVM 执行 new 指令为对象分配内存时,会在堆中申请一块内存;而这块内存的回收,便是由垃圾收集器负责的;实际上,不只是垃圾回收,对象的内存分配,也取决于当前使用的垃圾收集器类型,这点也好理解,比如我将内存分代了,那新分配的内存一般都是在新生代分配,而不是在老年代分配。

一个 JVM 可能同时会使用多个垃圾收集器,我们讨论回收策略的时候,其实是在讨论某一款 垃圾收集器 的策略,而不是在讨论某款 虚拟机 的策略。

所有的垃圾收集器要解决的问题,都可以概括成两个:怎么判断对象可以被回收、怎么回收这些垃圾对象。

阅读更多

JVM 内存结构

前言

在讨论 JVM 内存结构前,我觉得有几点需要先明确一下:

  • 我们说的 JVM 本质上就是一个进程,这个 JVM 进程执行 由我们编写的代码编译成的 字节码;也就是说,我们编写并运行了一个 Java 程序,其实是启动了一个 JVM 进程 用来解析运行我们的代码(解释执行);所以我们讨论的内存结构,都是在进程的层面来讨论的,而不是系统层面;
  • android 并不算 JVM,无论是 Dalvik 还是 ART ,因为他并不符合 Java 虚拟机规范,比如他并不能直接执行 Java 字节码;但是他很多地方跟 JVM 其实是一样的,所以这里讨论的内存结构也适用于 android;不过在栈帧里,安卓使用的是寄存器而不是操作数栈;
  • 在规范中,并没有对 堆(Heap) 进行进一步的划分,年轻代老年代这些都是从 GC 的层面来进行划分的;

阅读更多

Handler 源码解析

初始化

Looper、MessageQueue 初始化

  1. 先调用 Looper.prepare(),会创建 Looper 实例放入 ThreadLocal 中
  2. Looper 的构造函数会创建消息队列 MessageQueue
  3. MessageQueue 的构造函数会通过 nativeInit 调用到 native 层
  4. nativeInit 方法会创建 native 层的消息队列 NativeMessageQueue
  5. NativeMessageQueue 的构造函数会创建 native 层的 Looper,放入线程中(pthread_setspecific)
  6. Looper 的构造函数会创建 eventfd,然后调用 rebuildEpollLocked 方法创建 epoll 实例
  7. rebuildEpollLocked 方法会调用 epoll_create1、epoll_ctl 创建 epoll 实例并添加 eventfd 的可读事件

在 android 6.0 前,native 的 Looper 使用的是匿名管道 pipe,pipe 会创建两个虚拟文件,一个用来读一个用来写;6.0 开始,Looper 改成了 eventfd , 只会创建一个虚拟文件,而且性能更好

阅读更多