了解虚拟机JVM
了解JDK体系结构
学习JAVA虚拟机的组成部分
调用java.Math.java时会执行以下步骤:
1调用类装载子系统。
2将字节码文件装在运行时数据区(或Java虚拟机内存区域)。
3调用字节码执行引擎执行内存当中的代码。
紫色为每个线程私有的,黄色为所有线程公有的
学习虚拟机栈(装线程的栈)
虚拟机栈(这里的栈(线程)):(int a) ,每个线程存放在虚拟机栈的不同位置,彼此独立。所有的局部变量都会放到这里。在虚拟机栈的各个线程空间的当中,每个方法有一个独立空间(栈帧),方法遵循后入先出,(后调用先结束,先调用后结束(一般是main最后结束))
通过存储原理理解局部变量表和操作数栈:
eg: int a=1;
(1)将1存入操作数栈
(2)给a在局部变量表当中分配一块空间
(3)将1从操作数栈出栈
(4)将1存入给a分配的内存空间当中
这时 c=a+b (b=1)
(1)将a和b的值装载到操作数栈当中来
(2)在操作数栈当中把栈顶的两个元素弹出来,然后做运算
(3)将运算结果重新压回操作数栈
(4)给c在局部变量表当中分配内存空间
(5)将2出栈
(6)将2放到c所在的内存空间当中
以上每个过程字节码执行引擎会不断修改程序位置
如果局部变量为一个对象(栈和堆之间的关系 )
eg:User user =new User();
这个user对象分配在堆上,局部变量表与user之间关系:局部变量表的指针(或者说地址)指向堆中的user
总结:栈当中的局部变量为对象时,其存储的是堆当中的地址.
如果局部变量为一个静态变量对象(堆和方法区之间的关系)
Eg: public static User user =new User();
一般静态变量都存放在方法区当中,对象存在堆当中,然而在这种情况当中user对象存储在堆当中,方法区当中的user存储的是堆中的地址.
总结:对于静态变量对象,栈中的变量(存储的是地址)指向堆中变量,方法区当中的静态变量(存储的也是地址)指向堆当中的变量.
动态链接
先了解
符号引用:方法,名称等等
比如 User user =new User();user为符号引用。这些都存储在了一个方法区里。
直接引用:直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄
动态链接就是将符号引用转化为直接引用
程序计数器
每个线程在程序计数器当中都有一块专属空间专门
用来存储Java下一行马上要运行的代码的地址
堆
主要用于存储Java对象实例和数组
学习堆的迭代机制![](https://img-blog.csdnimg.cn/direct/f9ddd34c69604faabeadfce0004c621f.png)
年轻代占1/3(伊甸园:s0:s1= 8:1:1) 年老代占2/3
过程:创建对象存储在伊甸园当中,满的时候执行gc(垃圾回收) [由字节码执行引擎执行垃圾收集线程]
GC Root:
就是垃圾回收根对象:GC Root对象主要包括以下几类:(都是不清理的,作为根root)
-
虚拟机栈中的局部变量表中引用的对象。这些对象是当前正在被调用的方法里的局部变量所引用的。
-
方法区中的静态变量引用的对象。这些对象是由类的静态字段以静态方式持有的。
-
方法区中的常量引用的对象。这些常量通常是使用static final修饰的。
-
本地方法栈中Native方法引用的对象。这些对象是通过JNI(Java Native Interface)技术实现的本地方法所引用的。
[在可达性分析算法当中使用GC ROOT执行以下操作:]
通过从上面这些对象,查看这些对象调用的对象,(以及调用对象的调用对象的调用对象....)。只要有被其调用到,那么就不会被清理.(这时但凡被调用的都会被标记)其他所有没有找到的对象(未被标记的)都是垃圾,都要被回收.
Minor GC:
它主要关注的是新生代(Young Generation)的内存回收
过程:
1新创建的对象首先会被分配到伊甸园区。当伊甸园区的空间不足以容纳新对象时,会触发Minor GC。
2垃圾回收器开始扫描伊甸园区和Survivor区中的对象,找出所有仍然被引用的对象并标记它们
3标记完成后,存活的对象会被复制到其中一个Survivor区(如果Survivor区有足够的空间)。同时,伊甸园区和另一个Survivor区中的不存活对象(即垃圾对象)的内存空间会被回收。
4在下一次的Minor GC中,Survivor区的角色会交换。例如,在一次GC后,原本存放存活对象的Survivor区会变成接收新存活对象的区域,而原本空闲的Survivor区则变为接收从伊甸园区复制过来的存活对象的区域。
5当对象的年龄达到一个预设的阈值(默认是15,由参数-XX:MaxTenuringThreshold
控制)时,这个对象会被晋升到老年代(如果把一批对象放到survivor区,且这一批对象的总大小超过survivor区域的50%【-XX:TargetSurvivorRatio可以指定比例】就可以直接进入老年代)
6Minor GC结束。此时,伊甸园区被清空,如果后续还有新对象创建导致伊甸园区再次满,将会触发下一次Minor GC
full GC:
对老年代回收,当老年代空间不足或者为了整理碎片化的内存时,会触发Full GC. Full GC的执行可能导致应用程序的暂停时间较长,因为它需要遍历整个堆空间来查找和回收不再使用的对象
过程:1使用可达性分析算法(使用GCRoot)清理所有未被标记的对象.最后为了提高内存的利用率和后续对象分配的效率,垃圾回收器会进行内存压缩操作。在压缩阶段,垃圾回收器会将存活的对象移动到一起,消除内存碎片,以便为新对象分配连续的内存空间。
本地方法栈
本地方法栈为每个线程提供了一个独立的内存区域,用于使用其他编程语言(如C、C++等).
eg在关于线程的start()方法源码当中有一个start0()方法调用的就是c或c++语言
方法区
存放常量 ,静态变量,类信息。
JVM调优
调优目的:减少 GC(主要减少full gc).也就是减少STW(stop the word 暂停所有线程搞垃圾回收)
调优工具eg:
阿里巴巴调优工具:ARthas
或者VisualVM