jvm调优

jvm调优

一、代码是怎么跑起来的

  首先我们应该知道代码是怎么跑起来的。一般我们写完java代码都是后缀为“.java”后缀的代码,然后打成jar包或者war包部署在服务上,打包的过程中,“.java”文件就被编译成了“.class”文件

  而jvm想将字节码文件运行起来,就需要先加载进来。

二、类加载机制

  类加载过程

  加载——》验证——》准备——》解析——》初始化——》使用——》卸载

  我们在用到这个代码的时候,才会加载

  验证就是看看字节码文件的内容是否符合jvm规范

  准备就是为一些被static修饰的变量分配内存空间,并初始化值,如果加了final这个阶段也会复制

  解析:解析就是符号引用替换为直接引用的过程。直接引用是可以找到这个对象的地址的。

  初始化:赋值,初始化子类的时候要先初始化父类

三、双亲委派机制

  java中有启动类加载器(核心类库)、扩展类加载器(libext)、应用程序类加载器(环境变量所指定的类,也就是写的java文件)、自定义类加载器(可与防止被人反编译)

  启动类加载器——最上层

  扩展类加载器——中间一层

  应用程序类加载器——第三层

  自定义加载器——最下面

  就是说应用程序类加载器要加载的时候,他首先会委派自己的父类加载器去加载,最终传到顶层的类加载器去加载。

  顶层加载不了的下沉。这样可以确保不同的类加载器可以加载到相同的object对象。

四、内存划分

  堆内存

  方法区

  本地方法去

  虚拟机栈

  程序计数器:执行代码指令,因为我们写的代码,计算机是不认识的,字节码是计算机理解的语言,所以当字节码文件被加载后,是使用字节码执行引擎,来执行指令的。程序计数器就是记录当值执行的字节码指令的位置的。线程都会有自己的程序计数器。

五、新生代里存活的对象

  大部分都是朝生即死的,比如局部变量引用的对象,在方法运行时,是存在的,方法弹栈以后就成垃圾数据了,被static修饰的静态变量往往存活时间长,会进入老年代。

六、JVM内存的几个核心参数  

  -XmsJava堆内存的大小      一般将Xms和Xmx设置成一样的,因为如果不一样堆内存会有一个膨胀收缩的过程。

  -XmxJava堆内存的最大大小

  -XmnJava堆内存中的新生代大小,扣除新生代剩下的就是老年代的内存大小了

  -XX:PermSize:永久代大小

  -XX:MaxPermSize:永久代最大大小

  -Xss:每个线程的栈内存大小

  堆内存空间设为3g,新生代2g是比较合理的,如果新生代只有1g,扣除老年代的,那么yang GC会很频繁的。

七、JVM的对象

  只要被局部变量或静态变量引用的对象都不会被回收。

八、JVM算法

  复制算法的缺点就是压缩了内存

  动态年龄判断,比如s0区里两个2岁的随想加起来已经超过了一半的内存空间,那么两岁的会进入老年代,1+2+3+4.。。+n的对象超过一半,大于N的对象会进入。

九、大对象

有一个JVM参数,就是“-XX:PretenureSizeThreshold”,可以把他的值设置为字节数,比如“1048576”字节,就是1MB

 十、Minor gc过后对象太多怎么办

  比如eden区存活的对象太多,survivor区放不下,那么这些对象就要进入老年代。

  所以有了空间担保规则

  就是说survivor区放不下,但是老年代也放不下的话?怎么办,所以Minor gc前,jvm会先检查老年代可用空间是否大于新生代所有对象的综合。

  如果不大于。就要设置一个参数,空间担保,可以看看老年代可用空间是否大于以前移入的平均大小。如果这个都小于就会Fall gc

  

原文地址:https://www.cnblogs.com/gushiye/p/14020174.html