JVM运行时数据区和JMM

技术标签: JVM  JVM运行时数据区  JVM内存模型

一、JVM运行时数据区


        Java程序运行时,会基于类加载机制将类文件加载到JVM,并将类中的信息分解后放置到JVM的各个模块,以提供运行。程序(Java类)由数据、指令和控制(return等)组成。下面是JVM运行时数据区:

1、程序计数器

        当前线程正在执行Java方法时,计数器存储的当前方法正在执行的字节码指令的地址和行号;若当前线程正在执行Native方法时,计数器存储的值为Undefined。并且程序计数器是唯一一个不会涉及OutOfMemoryError的区域。

2、虚拟机栈(stack)

        虚拟机栈用于存储当前线程正在运行方法的数据、指令和返回地址。当线程请求的栈深度大于虚拟机运行的最大深度,则会抛出StackOverflowError;虚拟机栈动态扩展时(现在大部分Java虚拟机的虚拟机栈都支持动态扩容,少部分不支持),若无法申请到足够的内存空间,则会抛出OutOfMemoryError。


    1)、局部变量

        局部变量分为基本类型和引用类型:基本类型直接进行存储,并且long和double类型会存储两个局部变量空间(Slot);引用类型会则:1、指向Heap中的指针、对象的句柄或者位置 2、returnAddress地址(返回地址类型)。内存空间一经过分配就不会再进行改变,包括运行期间不能进行调整。

    2)、操作数栈

       出栈和入栈

    3)、动态链接

       常量池中查找父类引用指向子类对象的真实实例对象。

    4)、出口

        return、try catch 等控制程序

3、本地方法栈(Native Method Stack)

        本地方法栈除了处理对象(native方法)不同,其他与虚拟机栈一致,并且在HotSpot中直接将两个进行合并,所以该部分也可能包StackOverflowError和OutOfMemoryError(原因与虚拟机栈相同)。

4、方法区

    方法区与永久代是不完全等同的,但是很多时候为了方便理解,基本都理解为一致。方法区与堆一样:可以是非连续的内存空间,可以设置孤独的内存大小或者设置可以扩展的内存大小,可以不实现垃圾回收器。

        1)、类信息    存放类的版本号、字段、方法等信息

        2)、常量(常量池)

    常量池并不是在编译器存储之后后续就不会动态扩展的区域,比如在运行期间String的intern()方法可以将常量放入常量池中,所以也会存在OutOfMemoryError问题。

        3)、静态变量

        4)、JIT(just-in-time ) 动态代理时候动态生成的代码

5、堆(Heap)

    Java堆(Heap)方法区是线程共享的,跟随Java虚拟机的生命周期,所以不会有线程安全问题。所有对象实例及数组都会分配在堆中,JIT、逃逸分析除外。堆中还会有TLAB(Thread Local Allocation Buffer):Java线程的私有缓存空间。

6、直接内存

    直接内存并不是运行时数据区的一部分,但是也是Java操作内存的一种方式。JDK4中引入New Input/Output类,可以使用Native函数直接分配堆外内存,目的是可以不用在本地方法栈和虚拟机栈中复制数据。虽然,不会受到JVM堆初始化和最大内存设置的限制,但是会受限于本机内存的限制,若堆内存分配空间过大,该部分没有内存可以用,也会照成OutOfMemoryError。

二、运行时数据区与内存溢出异常

    由上面可知,运行时数据区与内存溢出、栈异常的关系如下:



三、JVM内存模型(JMM)

   

    由于对象的生命周期是不一样的,所以需要对JMM进行分代。JMM分为新生代、老年代和永久代(在JDK1。8将永久代替换为Meta Space,一个可以无限扩展的内存空间),并且新生代与老年代为1:2,因为需要做内存担保。新生代为分eden区、S0区(from Survivor)、S1(to Servivor)区并且比例为8:1:1。根据计算得知,98%的对象会在minor gc的时候会被回收掉。



四、JVM常用配置参数

   1、jvm配置

    XX比X的稳定性更差,并且版本更新不会进行通知和说明。

1、-Xms   s为strating,表示堆内存起始大小

2、-Xmx   x为max,表示最大的堆内存

3、-Xmn  n为new,表示新生代大小

4、-XX:SurvivorRator=8    表示堆内存中新生代、老年代和永久代的比为8:1:1

5、-XX:PretenureSizeThreshold=3145728   表示当创建(new)的对象大于3M的时候直接进入老年代

6、-XX:MaxTenuringThreshold=15              表示当对象的存活的年龄(minor gc一次加1)大于多少时,进入老年代

7、-XX:-DisableExplicirGC    表示是否(+表示是,-表示否)打开GC日志


    2、对象进入老年代的条件

1、-XX:PretenureSizeThreshold=3145728   表示当创建(new)的对象大于3M的时候直接进入老年代

2、-XX:MaxTenuringThreshold=15              表示当对象的存活的年龄(minor gc一次加1)大于多少时,进入老年代

3、当同年龄的所有对象的大小总和 > Survivor空间的一半 ,则也会进入老年代



版权声明:本文为博主原创文章,遵循版权协议,转载请附上原文出处链接和本声明。
本文链接:
快乐赛车 快乐赛车投注 秒速时时彩 幸运飞艇官网 上海时时乐 幸运飞艇官网 智慧彩票投注预测APP 飞速赛车平台 幸运赛车 秒速时时彩