1.
内存分配原理。
当new 一个对象时JVM先在常量池中查找该类的符号引用,然后判断是否被java类装载器,加载,解析和初始化。如果没有,首先由java类装载器进行加载解析和初始化。
然后首先试图在**TLAB** ThreadLocalAllocation 本地线程分配缓冲区分配空间。,TLAB是线程私有区域,包含在Edge空间内,目的是为了线程安全,同时能够提升内存分配吞吐量,称之为快速内存分配。
当**TLAB**分配空间失败后,通过加锁机制,直接在Edge空间分配内存。当Edge无法分配内存时,执行MinorGC回收,直到可以分配为止。
分配好内存后,将对象实例化,首先将分配的内存空间写零操作,这是为什么类中的未初始化的变量会默认初始化。然后将引用入栈。同时更新PC计数器。
内存分配流程就是:
加载类——-》TLAB分配内存———-》TLAB失败,Edge分配内存——》对象实例化(分配空间写零)——–》引用入栈——》更新PC计数器。
2.
GC回收:
- 垃圾标记:根搜索算法,引用计数算法。引用计数算法无法标记出已经死亡但存在相互引用的对象,所以JVM采用根搜索算法,
- 垃圾回收算法: 标记-清除(Mark Sweep),复制,标记–压缩。
标记清除算法将回收任务分为两个阶段执行:垃圾标记,内存释放。 相对于复制和标记-压缩回收算法,标记-清除算法执行效率低下,且由于被执行的内存回收的无用对象所占用的空间可能是一些不连续的内存块,将会产生一些内存碎片,导致后续没有足够的内存空间分配给比较大的对象。
复制算法被广泛用在新生代
当执行MinorGC(新生代垃圾回收)时,Edge空间中的存活对象会被复制到To Survivor空间内,并且之前已经经历过一次MinorGC且在From Survivor空间存活下来,且同样年轻的对象也会被复制到To Survivor空间内。
特殊情况1:当Edge 和From Survivor空间内的对象超过分代年龄,将直接进入年老代。
特殊情况2:当To Survivor空间超过阈值时,Edge和From Survivor直接进入年老代。
当执行完MinorGC后,Edge和From空间会被清空,接下来From和To区域互换,保证两个Survivor空间中一块必须是空的,这就是复制算法。
3.
垃圾回收器:
- Serial : 新生代, 复制算法,串行回收,stop-the-world
- Serial Old :年老代,标记-压缩,串行回收,stop-the-world
- ParNew: 新生代,复制算法,并行回收,stop-the-world,多线程。
- Parallel : 新生代,复制算法,并行回收,stop-the-world,吞吐量优先。
- Parallel Old:年老代,标记压缩,并行回收,stop-the-world
CMS:Concurrent Mark Sweep,年老代,标记-清除,stop-the-world
1,初始标记–并发标记—再标记—-并发清除。G1 ,重塑JAVA 堆区,把整个堆划分为2048左右个Region,执行过程:
初始标记—–根区域扫描—–并发标记———再标记——清除—–拷贝
942

被折叠的 条评论
为什么被折叠?



