目录
前言
记录一下内存相关的内容
正文
Java虚拟机
Java虚拟机是一台“抽象的计算机”,它拥有自己的处理器,堆栈,寄存器以及相应的指令系统。
Java虚拟机疲敝了与操作系统相关的平台信息,使得Java程序只需要生成该虚拟机上运行的目标代码,就可以在多个平台上运行。
JVM运行时数据区域
分为两个部分,线程独占和线程共享。
线程独占部分
每个线程都会有它独立的空间,随着线程生命周期而创建和销毁。
虚拟机栈,本地方法和程序计数器
线程共享部分
所有线程都可以访问这块内存数据,随虚拟机或者GC而创建和销毁。
方法区,Java堆
方法区
JVM用了存储加载的类信息,常量,静态变量和编译后的数据等。
堆内存
JVM启动时创建,存放对象的实例。垃圾回收器主要就是管理堆内存。
如果满了,就会出现OutOfMemoryError
虚拟机栈
每个线程都在这个空间有个私有的空间。
线程栈由多个栈帧(Stack Frame)组成。
一个线程会执行一个或多个方法,一个方法对应一个栈帧。
强,软,弱,虚引用
强引用 : 强引用的对象,垃圾回收器绝对不会回收,宁愿OutOfMemory异常
软引用 : 软引用的对象,当内存不够时,垃圾回收器会回收,如果回收的内存还是不够,就抛出OutOfMemory
弱引用 : 弱引用的对象,垃圾回收器不会管当前内存是否足够,都会回收
虚引用 : 如果一个对象仅持有虚引用,在任何时候都可能被垃圾回收器回收,只是当它回收时会收到一个系统通知。
垃圾标记算法
引用计数算法
每一个对象都有一个引用计数器,当对象被引用时就加1,引用失效就减1。当计数为0时则将对象置为可回收的“垃圾对象”。
根搜索算法
垃圾收集算法
标记-清除算法
对标记可回收的对象就行回收。
内存碎片化,消耗大
复制算法
先把内存一分为二,每次只使用其中一块区域,垃圾搜集时,将存活的对象拷贝到另外一个区域,然后对之前区域就行全部回收。
缺点:可用内存变小
标记-压缩算法
在标记可回收的对象后,将所有的存活对象压缩在内存的一端,让他们排在一起,然后对端边界外的内存进行回收。
分代收集算法
根据对象生命周期长短进行放在不同的区域。
内存泄露
一个不再被程序使用的对象或变量依旧存活在内存中无法被回收
内存溢出
当程序申请内存时,没有足够的内存提供给程序使用。
out of memory
内存抖动
短时间内多次内存的分配和释放。
主要原因是短时间内多次创建对象。
频繁GC会导致画面卡顿,因为其他线程会被挂起等待GC完成。
PS : UI绘制是16ms一帧,如果没有规定时间内绘制好久会出现卡顿。
内存分析工具
MAT
Android Studio Profiler