编程语言爱好者Java 核心技术

JVM内存模型

2021-05-04  本文已影响0人  蓝梅

一、jvm内存模型图

JVM内存模型

二、内存模型描述

堆:所有新建对象都会在堆中开辟内存

方法区(本地内存):存放类信息,方法信息,静态变量等数据(不设置默认21M,建议最好设置,且设置一样,很多程序因为该值设置问题,导致fullGC,fullGC后如果未设置,则会自动扩容

由于调整元空间的大小需要Full GC,这是非常昂贵的操作,如果应用在启动的时候发生大量Full GC,通常都是由于永久代或元空间发生了大小调整,基于这种情况,一般建议在JVM参数中将MetaspaceSize和MaxMetaspaceSize设置成一样的值,并设置得比初始值要大,对于8G物理内存的机器来说,一般我会将这两个值都设置为256M。)

堆和方法区属于线程共享

栈(java虚拟机栈):开启一个线程时建立,栈里面包含 局部变量表(用于存放方法执行时产生的变量)、操作数栈(执行程序操作,比如 加减乘除)、动态链接(存放方法的变量,类似于 执行方法的内存地址,运行时才能解析)、方法出口(方法返回)(默认1M)

程序计数器:当程序执行到那个步骤会记录在程序计数器(个人理解,应为CPU切换,导致线程被挂起,唤醒时需要从程序计数器中获取执行位置,继续执行)

本地方法栈:存放native方法执行时的变量等元素(目前基本上用不到,为了java最开始兼容其他程序准备的)

三、GC

对象初始化时先放入Eden区,当Eden区超过设置大小时,发生minor gc,回收不了的对象,转移到S区,后面再发生minor gc时,是回收Eden区和Survivor区一起,第一次转移到s0,第二次就会转移到s1区;每个对象经历一次GC,则会在对象头中记录GC年龄,默认且最大15,则会被迁入老年代,当老年代到达设置大小时,则会发生full gc,如果gc回收的内存不够,则会抛出OOM(内存溢出)异常;

每次GC都会发生stop the world(工作线程停止工作,防止产生新垃圾),每次JVM调优都是为了减少GC次数以及时间

GC时怎么判断该对象是否可以回收,根据GcRoot引用来查找,虚拟机栈和本地方法都可以算是GcRoot的一部分

虚拟机工作机制

四、参数设置

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

-Xss:每个线程的栈大小

-Xms:初始堆大小,默认物理内存的1/64

-Xmx:最大堆大小,默认物理内存的1/4

-Xmn:新生代大小

-XX:NewSize:设置新生代初始大小

-XX:NewRatio:默认2表示新生代占年老代的1/2,占整个堆内存的1/3。

-XX:SurvivorRatio:默认8表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存。

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

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

-XX:MetaspaceSize: 指定元空间触发Fullgc的初始阈值(元空间无固定初始大小), 以字节为单位,默认是21M左右,达到该值就会触发full gc进行类型卸载, 同时收集器会对该值进行调整: 如果释放了大量的空间, 就适当降低该值; 如果释放了很少的空间, 那么在不超过-XX:MaxMetaspaceSize(如果设置了的话) 的情况下, 适当提高该值。这个跟早期jdk版本的-XX:PermSize参数意思不一样,-XX:PermSize代表永久代的初始容量。

上一篇 下一篇

猜你喜欢

热点阅读