JVM 内存模型

JVM 内存模型

JVM 整体结构及内存模型

JVM 内存模型图涉及变量代码如下:

class Test {

    public static Order order = new Order();

    public int test() {
        int a = 1;
        int b = 2;
        User user = new User();
        int c = a + b;
        return c;
    }

    public static void main(String[] args) {
        new Test().test();
        System.out.println("===test方法出口返回===");
    }
}

class User {
}

class Order {
}
JVM内存模型.png

JVM 为为每个线程分配了独立的栈空间,程序计数器,本地方法栈。在一个线程内,方法的调用会给方法分配一块栈帧,每个栈帧都有独立的局部变量表,操作数栈,动态链接,方法出口(保证了方法内部局部变量的作用范围)

test 方法操作数栈变化:在局部变量表中分配给变量 a 内存空间,将整数 1 压入操作数栈,然后出栈赋值给变量 a,在给变量 b 分配内存空间,将整数 2 压入操作数栈,然后出栈赋值给变量 b,从局部变量表中找到 a 和 b 的值,存入操作数栈,进行整数 add 操作,得到结果压入操作数栈,出栈赋值给变量 c,从局部变量表得到 c 的值,压入操作数栈,执行 return 返回。


操作数栈变化过程.png

GC 垃圾回收机制

Eden 区满了之后会执行 minor GC 清理 Eden 区和非空的 Survivor 区,GC 之后将存活对象移至空的 Survivor 区,并将分代年龄+1,分代年龄到 15 之后会将存活对象存入年老代,当年老代满了之后会执行 Full GC 清理年轻代,年老代和元空间,如果 Full GC 之后没有清理出空间就会出现 OOM(内存溢出)。 JVM 会根据 GC Roots 查找所有依赖的对象直到最后一个没有依赖的对象为止,将这些对象标记为非垃圾对象。每次 GC 会伴随 STW 机制。

什么是 GC Roots

JVM 中判断一个对象是否标记为可回收的对象是根据可达性分析算法,顾名思义,可达性分析需要知道当前对象(是否需要回收的对象)的起点,而这个起点对象在当前时刻一定是存活的,才能保证对当前对象是否需要回收的判断是正确的,所以 GC Root 表示:当前时刻存活的对象

GC Roots 包含以下几种:

  1. 方法中的局部变量
  2. 静态变量引用的对象
  3. 常量(被 final 修饰)
  4. 本地方法引用的对象
什么是 STW

Stop 一 the 一 World,简称 STW,指的是 Gc 事件发生过程中,会使得用户线程停止执行,产生应用程序的卡顿。

JVM 为什么会设计 STW 机制

在 GC 期间,如果用户线程不停止,可能刚刚根据 GC Roots 找到的非垃圾对象可能变成垃圾对象,使得 GC 未能回收。

JVM 内存参数设置

JVM参数设置.png

Spring Boot 程序的 JVM 参数设置格式(Tomcat 启动直接加在 bin 目录下 catalina.sh 文件里)

    ‐Xms2048M ‐Xmx2048M ‐Xmn1024M ‐Xss512K ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M

关于元空间的 JVM 参数有两个:-XX:MetaspaceSize=N 和-XX:MaxMetaspaceSize=N

-XX:MaxMetaspaceSize:设置元空间最大值,默认是-1,即不限制,或者说只受限于本地内存大小。

-XX:MetaspaceSize:指定元空间触发 Full GC 的初始阈值(元空间无固定初始大小),以字节为单位,默认是 21M,达到该值就会触发 Full GC 进行类型卸载,同时收集器会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过-XX:MaxMetaspaceSize(如果设置了的话)的情况下,
适当提高该值。这个跟早期 jdk 版本的-XX:PermSize 参数意思不一样,-XX:PermSize 代表永久代的初始容量。由于调整元空间的大小需要 Full GC,这是非常昂贵的操作,如果应用在启动的时候发生大量 Full GC,通常都是由于永久代或元空间发生了大小调整,基于这种情况,一般建议在 JVM 参数中将 MetaspaceSize 和 MaxMetaspaceSize 设置成一样的值,并设置得比初始值要大,对于 8G 物理内存的机器来说,一般设置为 256M。

StackOverFlowError

public class TestStackOverFlow {
    static int i = 0;
    public static void overflow() {
        i++;
        overflow();
    }

    public static void main(String[] args) {
        overflow();
    }
}

结论:-Xss设置越小,说明一个线程栈里能分配的栈帧就越少,但是对JVM整体来说能开启的线程数会更多。
JVM优化就是尽可能让对象都在新生代里分配和回收,尽量别让太多对象频繁进入老年代,避免频繁对老年代进行垃圾回收,同时给系统充足的内存大小,避免新生代频繁的进行垃圾回收。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容