一些对于Java性能调优的理解

Java性能调优

JDK体系结构图
一些对于Java性能调优的理解_第1张图片

一.深入字节码底层剖析JVM内存结构

图表示了JVM在程序中的作用
一些对于Java性能调优的理解_第2张图片
JVM虚拟机内部构成
一些对于Java性能调优的理解_第3张图片
(1)栈中存放局部变量,每一个线程运行时Java虚拟机都会给它分配一个栈空间,存放线程中的局部变量,堆中存放对象,也就是说如果存在对象局部变量,那么栈空间中就会存放一个指向堆的指针。
(2)方法区中存放常量+静态变量+类信息。
如果静态变量是一个对象,则在方法区中存放一个指针,指针指向堆中的一个地址,因为对象放在堆中。
(3)本地方法栈就是存放本地方法变量的栈空间。
栈帧概念:一个方法对应一块栈内存区域,存放方法自己的局部变量。
注意:栈,本地方法栈,程序计数器都是每个线程独有的;堆和方法区是线程之间共享的。

一些对于Java性能调优的理解_第4张图片
main方法内调用compute()方法,这个栈也是满足先进后出,main()方法先进入,先开始,最后一个出去,main()最后结束;FIFO

栈结构解析

一些对于Java性能调优的理解_第5张图片
局部变量表存放a,b,c这些变量;操作数栈存放1,2,30这些数字。方法出口存放函数间的调用后的位置。比如从math回到main后,记录main的开始位置。

堆结构解析
一些对于Java性能调优的理解_第6张图片
刚刚new出来的对象放在伊甸园区(Eden),堆是有大小限制,假设堆内存是600M,默认情况下,老年代占2/3,年轻代占1/3。Eden占1/3的8/10。
当伊甸园区被new出的对象放满后会启用minor gc(垃圾收集)。
想要搞明白垃圾收集,首先需要明白什么是GC roots;GC roots:一种根节点,线程的本地变量、静态变量、本地方法栈
垃圾收集首先从栈上,方法区上找出所有的GC roots,然后从GC roots出发,找到GC roots引用的对象,形成一条线索,直到找到最后一个对象,这个对象不再引用其他对象,这个链条上的对象叫做非垃圾对象,不在链条上的对象叫做垃圾对象把这些非垃圾对象直接放置再Survivor区中,然后JVM把伊甸园区整个空间内存全部释放,并且当这些非垃圾对象在Survivor中s0和s1中来回移动15代之后还未被回收,就会把这些对象放到老年代中,如果老年代被放满了,就会将它进行一次full GC,但是这时GC也不可能全部回收,因为你在使用它,这时就会遇到一个经典问题,OOM:OutOfMemoryError

二.调优

首先明确一个概念STW(stop the world),就是说在垃圾收集时,会把用户的线程停止,专心做垃圾收集,对于用户来说就会感觉到明显的卡顿。
为什么不能一边垃圾收集一边运行用户线程,运行时的线程会放在GC root中,但是运行结束后的线程,会让在GC root中的对象变成垃圾,排除在GC root外,会使收集GC root的过程变得很复杂。

Java虚拟机调优的目的就是减少垃圾收集的时间,因为垃圾收集会进行STW,会使使用起来的感受极差,卡顿现象
面对JVM调优,可以让其几乎不发生Full GC,频繁的Full GC会使系统效率变得极低,而minor GC对系统效率影响非常低,减少full GC,增多minor GC,就是进行内存分配调整,减少老年代区内存,增大Survivor区内存
一些对于Java性能调优的理解_第7张图片

你可能感兴趣的:(Java企业级项目)