JVM随笔(三)内存模型

JVM内存模型

    JVM内存模型与Java内存模型不是一个东西,很多人经常会搞混掉,JMM是java并发处理时针对CPU内存抽象出来的一个内存模型。JVM内存模型可以理解为JVM启动是开辟了一块内存,然后用于存放各种数据。


JVM随笔(三)内存模型_第1张图片

图中的运行是数据区就是JVM线程模型,包含一下几个部分组成 方法区、本地方法栈、虚拟机栈、程序计数器、堆。其中方法区和堆是JVM中所有线程共享的,其它几个区域是每一个线程私有的。

方法区

    方法区、永久代、元空间三者的区别是什么?

        方法区简单理解就是JVM的规范,相当于Java语法中的接口的概念,而永久代和元空间方法区的具体实现。永久代是JDK7之前方法区的实现方式,这块区域是放在JVM内存中的。而元空间是JDK8之后的方法区的实现,是为了取代永久代,元空间是存放在用户内存中,也就是os内存中,不受gc的管理。

        方法区中存放的是一些类的元数据, 比如类加载器加载.class文件之后会生成InstanceKlass对象,这个对象类的元数据信息,会放入方法区。

        方法区参数调优


JVM随笔(三)内存模型_第2张图片
查看元空间最大最小值

        -XX:MaxMetaspaceSize  -XX:MetaspaceSize
        调优方法就是最大最小调成一样大,防止元空间内存抖动,大小调成物理内存的1/32左右即可。

    虚拟机栈

        JVM是软件模拟虚拟机执行,是基于栈运行的,每个栈存放的内容是栈帧。一个方法的调用会在虚拟机栈中创建一个栈帧。方法执行完成之后会移除相应方法的栈帧。

        栈帧包含一下四个内容:

            局部变量表:保存局部变量

            操作数栈:指向指令操作的栈

            动态链接:指向元空间的对应的方法的MethodObject的内存地址    

            返回地址 保存线程:记录上一层栈帧执行的下一个字节码地址

            附加信息:保存一些附件信息,用于调试,但实际用处不多。    

    程序计数器

            字节码指令前面的index

JVM随笔(三)内存模型_第3张图片

    本地方法栈

         Java通过JNI调用C、C++动态链接库需要的栈,随着socket的发展,JNI技术已经用得非常非常少。

      堆区

            堆区是JVM内存模型中最主要的一块区域,存放对象,是垃圾回收器回收的区域。

            

JVM随笔(三)内存模型_第4张图片
堆内存区域划分

堆内存调优

    -Xms  -Xmx

    最小大小 物理内存的 1 / 64

    最大大小 物理内存的 1 / 4-Xms-Xmx

    调优策略同方法区相似,最大最小调成一致,防止内存抖动

什么对象会进入老年区?

    1、gc次数大于15依然存活的对象会进入老年代

        gc次数只能调整小于15的值,因为对象的年龄是记录下对象头的MarkWord字段里,其中用4个位表示对象的年龄

    2、大对象

        对象大小超过Eden区的一半

   3、动态年龄判断

        当survivor中相同年龄的对象空间和大于survivor的一半,则suvivior中大于等于改年龄的对象都进入老年代

    4、空间担保

        young gc之后存活的对象大于survivor的空间,则存活的对象会被空间担保分配到老年代。

JVM内存几块区域的指向关系

    方法区指向堆:方法区中存放的InstanceKlass会有指向其镜像类InstanceMirrorKlass的指针

    堆指向方法区:堆里存放的对象,对象头中有个KlassPointer指针指向的就是方法区中的InstanceKlass对象

    虚拟机栈指向堆:局表变量表中的引用对象指向的就是堆中的对象

    虚拟机栈指向元空间:虚拟机栈中的动态链接保存的就是元空间的对应MethodObject的指针。

你可能感兴趣的:(JVM随笔(三)内存模型)