性能优化|JVM内存分配机制
Posted 乐哉开讲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了性能优化|JVM内存分配机制相关的知识,希望对你有一定的参考价值。
JVM整体结构
-
堆 线程共享的区域,也是垃圾回收器要收集的区域,这地方主要保存用户创建的对象。例如 new User(),这个对象是保存在堆上面的。 -
栈 栈上面用来保存方法运行产生的局部变量、方法返回值和动态链接。 -
本地方法栈 是用来保存本地方法(native)执行的栈结构 -
方法区 在jdk1.8中已经更名为元空间了,这里面主要保存如下内容: -
类实例的引用 -
加载器的引用 -
字段修饰符(public、protect、private、default) -
字段的类型 -
字段名称 -
类型的全限定名 -
超类的全限定名 -
直接超接口的全限定名 -
类型标志(该类是类类型还是接口类型) -
类的访问描述符(public、private、default、abstract、final、static) -
类型信息 -
类型的常量池 -
字段信息 -
方法信息 -
类变量 -
各种引用 -
方法表 方法表是以非抽象类为纬度创建的数组,数组里面的元素是类中每个方法的直接引用,提升访问效率。 -
程序计数器 程序计数器是用来保存所在线程在切换前执行指令所在的行号,这个主要是解决多线程情况下,进行线程切换带来的问题,如果只有单线程,其实是不需要程序计数器的。
堆区域是如何进行划分的?
了解jvm的同学应该都知道,堆其实是分为新老年代的,这主要是为了进行垃圾回收而设计的一种结构
新老年代相关jvm参数
-
-XX:NewRatio 设置新老年代比例,如-XX:NewRatio=5 代表 新老年代比例为1:5,新生代占用堆内存的1/6,老年代占用5/6;jvm默认新老年代为1:2;需要注意的是如果程序启动指定了-XX:MaxNewSize值,那么设置比例的参数就会失效,老年代的值则为堆内存大小减去MaxNewSize; -
-XX:SurvivorRatio 设置新生代中eden和两个2个Survivo区域大小的比例,如-XX:SurvivorRatio=8,则eden:s1:s2=8:1:1,默认比例就是为8:1:1.
young GC发生在新生代中,FUll GC 发生在整个堆空间中,一般是老年代空间不够用就会出发FULL GC
逃逸分析
逃逸分析 主要用来分析方法内部的哪些对象是可以在在栈里面分配的,因为一般对象都是在堆中分配的,在堆中分配的对象,需要等待垃圾回收器进行回收,在回收之前会一直占用堆空间的,但是如果在一个方法内部,一个对象如果满足以下条件,是可以在栈中进行分配的:
-
是局部变量 -
没有将赋值给成员变量 -
没有被当作返回值跳出去
在jdk1.7之前需要使用-XX:+DoEscapeAnalysis参数进行开启,jdk1.7默认开启逃逸分析,如果需要关闭也是使用-XX:+DoEscapeAnalysis 参数进行关闭
什么是即时编译技术
我们先说下JVM的运行模式有哪几种?
-
解释模式 执行一行字节码就编译成一行机器码执行 -
特点:使用解释模式,JVM启动速度快,但是执行执行命令慢,需要一行一行进行编译 -
编译模式 先将所有字节码全部编译为机器码,然后一次性加载所有机器码执行 -
特点:使用编译模式,JVM启动速度会稍微慢点,因为需要进行编译,但是执行的时候几乎不需要有任何消耗 -
混合模式 使用解释模式执行代码,但是如果碰到一些热点或共用的代码片段,会采用编译模式执行,并且会将编译的内容缓存起来,减少重复编译,从而提高代码执行效率,这个也是JVM默认采用的编译模式,这个就是JIT(即时编译技术)
以上是关于性能优化|JVM内存分配机制的主要内容,如果未能解决你的问题,请参考以下文章