一、JVM类加载机制——自定义类加载器
二、JVM——对象内存分配机制
三、JVM内存模型
四、JVM垃圾收集算法和垃圾收集器
五、CMS垃圾回收器——三色标记算法
六、G1垃圾收集器
七、JVM调优实战——基本命令使用
八、JVM调优实战——arthas使用
九、大流量电商系统JVM调优案例

对象内存分配流程图

二、JVM——对象内存分配机制_对象创建

对象栈上分配

JVM通过逃逸分析,发现对象的作用域就在某个方法内,不会被外部访问,就把对象通过标量替换之后存储在栈上。
**逃逸分析:**就是分析对象的作用域,是否能够在一个方法范围内;
**标量替换:**通过分析确定对象不会逃逸之后,JVM不会创建该对象,而是用该对象的成员变量等价替代该对象。
栈上分配依赖逃逸分析和标量替换。

package com.ysy.JVM对象创建和内存分配机制深度剖析;

/**
 * @author shanyangyang
 * @date 2020/7/23
 * 开启逃逸分析和标量替换
 * -Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+PrintGC
 * 只开启标量替换,关闭逃逸分析
 * -Xmx15m -Xms15m -XX:-DoEscapeAnalysis -XX:+EliminateAllocations -XX:+PrintGC
开启逃逸分析,关闭标量替换
-Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+PrintGC

比较三种三种情况下的GC情况
 */
public class AlloctOnStack {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            alloc();
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    private static void alloc() {
        User user = new User();
        user.setId(1);
        user.setName("ysy");
    }
}

大对象直接进入老年代

JVM参数-XX:PretenureSizeThreshold可以设置大对象的大小,如果超过设置的大小,对象直接存入老年代。
**优点:**避免大对象在年轻代和老年代之间转换

package com.ysy.JVM对象创建和内存分配机制深度剖析;

/**
 * @author shanyangyang
 * @date 2020/7/23
 * -XX:+PrintGCDetails
 */
public class GCTest {
    public static void main(String[] args) {
        byte[] allocation1, allocation2, allocation3, allocation4, allocation5;
        allocation1 = new byte[2000 * 1024];
        allocation2 = new byte[10000 * 1024];
        allocation3 = new byte[8000 * 1024];
        allocation4 = new byte[8000 * 1024];
        allocation5 = new byte[3500 * 1025];
    }
}

TLAB 本地线程分配缓存

解决分配内存的并发问题;
每个线程在java堆中预先分配一小块内存,通过-XX:+UseTLAB设置。

AGE 对象达到一定年龄会进入老年代

对象第一进入survivor区域,年龄是1岁,然后每经过一次minorGC,年龄增加1岁。可以通过参数-XX:MaxTenuringThreshold来设置,默认15岁,CMS默认6岁。

对象动态年龄判断

当前Survivor区域中的一批对象的总大小大于Suvivor区域大小的50%。
年龄1+年龄2+年龄3+…+年龄n>50%;
则把年龄大于等于N的对象转移到老年代。

老年代空间担保机制

二、JVM——对象内存分配机制_jvm_02

finalize()方法

1、第一次标记并进行一次筛选。
筛选的条件是此对象是否有必要执行finalize()方法;
当对象没有覆盖这个方法时,直接回收

2、如果对象覆盖了finalize()方法;对象在该方法内部重新和GCROOT建立起连接没,就可以拯救自己。
注意:该方法只会执行一次,只有一次拯救自己的机会。