什么是JVM?
JVM是java就是java虚拟机,编写的java代码通过javac编译成可被java虚拟机执行的字节码,就是.class文件,其实是先编译成JVM指令,JVM指令再转成机器码执行。java之所以可以在不同机器上运行就是靠jvm实现,下载的jdk里面有jre(java runtime environment),jvm就包括在jre里面。安装的JDK包括JRE、java开发常用包等。
JVM的内存模型
Java在运行Java程序的时候会先将编译好的class文件载入到java虚拟机的内存模型中,对文件内容进行分类处理,JVM的内存模型主要由堆、栈、方法区、本地方法栈、程序计数器组成。堆里面存放的是数据,常量,静态变量、数组、链表以及对象等,JVM调优主要就是针对堆进行调优,栈里面存放的是方法,每一个方法会单独的开辟一块空间来存放方法,存放方法里面的常量、变量以及对象等,这些存的都是地址,地址指向的是堆里面的数据了。方法区是存放我们写的方法的地址,当执行器调用方法时会去方法区里面找到后只是它的地址,通过地址区栈里面找到对应的地址,本地方法区是存放java自带的方法,如线程的开启,new Thread().start()的调用,就是调用自带的方法开启线程。
堆
堆是JVM调优的重点,众所周知,jvm是自己回收垃圾,对于很多高并发或者编码产生的对象会使堆里面的垃圾过多,从而导致系统反应变慢甚至产生OOM,为什么会使系统反应变慢呢?因为java虚拟机自带垃圾回收,当堆里面的内存被占满时候会产生OOM,服务器就可能宕机了。肯定就卡死了,变慢还可能是jvm在频繁的进行垃圾回收,产生垃圾回收为什么会变慢呢?因为jvm在产生垃圾回收的时候会让服务停止,产生STW(stop the world),这个时候线程是被挂起的。用户发送的请求不会及时的响应。
什么时候需要JVM调优
堆区分为年轻代和老年代,所占空间比例为1:2,这些参数都是可以通过参数调的,默认是1:2,年轻代包括Eden,survivor1区和survivor2区,所占空间比例为8:1:1,程序刚开始产生的新对象存放在Eden区里面,当Eden存不下的时候会放在Survivor区,这时候就会产生yongGC,当多次yongGC后都没有清理掉的垃圾就会放入老年代,一般是15次,在对象的头部会记录改对象的年龄。但是当Eden区放不下对象时,这个对象会被放到老年代里面去。所以当年轻代和老年代频繁的发生yongGC和FullGC的时候程序是需要调优的,因为并发量很高会是系统相应速度变慢。具体还是要根据场景,下面列举两个场景。
场景一
当系统进行大量数据的导入导出时,由于时间较长,频繁的new对象,但是因为一直有引用,始终没有被释放掉,最终多次yongGC后没有回收掉就会进入老年代里面,导致老年代内存占满,产生OOM。
场景二
当进入订单高并发系统时,每秒产生的对象数据太多,导致Eden区很快被占满,年轻代频繁的YongGC,也会导致系统相应缓慢
总结
内存模型是JVM调优的基础,涉及到大的系统或者是并发量高的系统都必须要进行JVM调优设置