JVM 内存结构
前言
在讨论 JVM 内存结构前,我觉得有几点需要先明确一下:
- 我们说的 JVM 本质上就是一个进程,这个 JVM 进程执行 由我们编写的代码编译成的 字节码;也就是说,我们编写并运行了一个 Java 程序,其实是启动了一个 JVM 进程 用来解析运行我们的代码(解释执行);所以我们讨论的内存结构,都是在进程的层面来讨论的,而不是系统层面;
- android 并不算 JVM,无论是 Dalvik 还是 ART ,因为他并不符合 Java 虚拟机规范,比如他并不能直接执行 Java 字节码;但是他很多地方跟 JVM 其实是一样的,所以这里讨论的内存结构也适用于 android;不过在栈帧里,安卓使用的是寄存器而不是操作数栈;
- 在规范中,并没有对 堆(Heap) 进行进一步的划分,年轻代老年代这些都是从 GC 的层面来进行划分的;
Handler 源码解析
初始化
Looper、MessageQueue 初始化
- 先调用 Looper.prepare(),会创建 Looper 实例放入 ThreadLocal 中
- Looper 的构造函数会创建消息队列 MessageQueue
- MessageQueue 的构造函数会通过 nativeInit 调用到 native 层
- nativeInit 方法会创建 native 层的消息队列 NativeMessageQueue
- NativeMessageQueue 的构造函数会创建 native 层的 Looper,放入线程中(pthread_setspecific)
- Looper 的构造函数会创建 eventfd,然后调用 rebuildEpollLocked 方法创建 epoll 实例
- rebuildEpollLocked 方法会调用 epoll_create1、epoll_ctl 创建 epoll 实例并添加 eventfd 的可读事件
在 android 6.0 前,native 的 Looper 使用的是匿名管道 pipe,pipe 会创建两个虚拟文件,一个用来读一个用来写;6.0 开始,Looper 改成了 eventfd , 只会创建一个虚拟文件,而且性能更好
共计 12 篇文章,2 页。