三、JVM内存模型

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

一、JVM内存总共分为5个部分,下面我们就从这5个部分结合代码分别进行介绍:

在这里插入图片描述

package com.ysy.内存模型;

import java.util.ArrayList;

/**
 * @author shanyangyang
 * @date 2020/7/7
 */
public class MemTest {
    public static ArrayList<Integer> arrayList = new ArrayList<>();
    public String str = "abc";
    private final Integer num = 1;

    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        MemTest test = new MemTest();
        int c = test.add(a, b);
        System.out.println(c);
    }

    public int add(int a, int b) {
        return a + b;
    }

}

类装载子系统将编译后的MemTest.class文件装载入JVM虚拟机中。

二、JVM内存参数设置

springboot的JVM设置参数直接加在tomcat启动的catalina.sh文件里。

关于元空间的参数配置:-XX:MetaspaceSize=N和-XX:MaxMetaspaceSize=N
-XX:MetaspaceSize:指元空间触发fullgc的初始阀值,默认21M。可以弹性变化。
一般建议将MetaspaceSize和MaxMetaspaceSize的值设置一样大,对于8G物理内存,建议将这两个值设置为256M。
大流量电商系统JVM调优案例

三、StackOoverflow示例

-Xss设置为128K,很快方法就会报错,栈溢出。
-Xss设置的越小,说明一个线程栈里面可以分配的栈帧就越少,但是JVM整体来说开启的线程数会越多。

package com.ysy.stackoverflower示例;

/**
 * @author shanyangyang
 * @date 2020/7/18
 * 设置栈大小为 -Xss128k
 */
public class StackOverFlower {
    static int count = 0;

    static void redo() {
        count++;
        redo();
    }

    public static void main(String[] args) {
        try {
            redo();
        } catch (StackOverflowError stackOverflowError) {
            System.out.println(count);
        }
    }
}

四、JVM内存模块介绍

# 1、程序计数器

最小的一块内存区域,它是线程独享的,指向当前线程执行的字节码;字节码解释器工作时,通过改变程序计数器的值来取出下一条需要执行的命令。

2、堆(JVM垃圾回收器)

在这里插入图片描述
是最大的一块内存区域,它是所有线程共享的;几乎所有的对象实例都存放在该区域。
我们平时在java中经常提及的jvm垃圾回收,主要涉及的就是这块的内存;因此我们“堆”也被称为“GC堆”。
根据垃圾回收的原则:我们又把堆分为老年代和年轻代,将年轻代进一步的划分为eden区域、from survive和to survive区域;

堆大小 = 老年代+年轻代

2.1 年轻代
在这里插入图片描述
程序创建对象都是从年轻代开始的;jvm只会拿出eden和一块survive区域出来给对象分配地址,也就是说总有一块survive区域是空着的

2.1.1 未进行GC时,对象分布在eden和from survive区域中,to survive区域是空的;
2.1.2 紧接着发生GC,Eden区域中的对象都会被复制到to survive区域中,而form survive区域中的对象会根据对象年龄来决定去向;
2.1.3 -XX:MaxTenringThreshold设置一个值,大于这个值的对象移动到老年代中,小于这个值的对象移动到to survive区域中;经过这次GC之后,Eden区域和form survive区域会空出来;
2.1.4 此时to survive和from survive完成了角色更替;
上面描述的就是一次minor GC的过程;如果to survive也被填满了,那就将to survive中所有的对象移动到老年代中;
移动就是复制,因为年轻代使用的复制算法

2.2 老年代
用于存放经过多次minor GC依然活着的对象(老兵不死,只是凋零),对象不死,只是进入了老年代中;
老年代中的垃圾回收为FUll GC
Full GC采用的是标记-清除算法。不同的垃圾回收器使用的算法不尽相同。

3、方法区-元空间

在这里插入图片描述
方法区也被称为永久代,用于存放虚拟机加载的类信息、静态变量、运行时常量池,是各个线程共享的区域。
运行时常量池是方法区的一部分,用于存放编译器产生的各种符号引用。

4、虚拟机栈

在这里插入图片描述
在这里插入图片描述
和程序计数器一样,也是线程私有的,它的生命周期与线程相同。每一个方法被调用直至执行结束的过程,都对应着一个栈帧在虚拟中从入栈到出栈的过程。

5、本地方法栈

与虚拟机栈基本类似,也是私有的,区别在于虚拟机栈为虚拟机执行java程序服务,而本地方法栈为虚拟机使用到的native方法服务。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值