JVM知识点学习

JVM知识学习

1. JVM的位置(jre中)

运行在操作系统之上(window,Linux,Mac…),操作系统运行在硬件体系之上。

2. JVM体系结构 JVM体系结构

注意:

  1. 栈,程序计数器不可能存在垃圾回收
  2. JVM调优大部分是在调堆

3.类加载器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XVEfvfj4-1598964975996)(./类加载器.png)]

  1. 作用: 加载class文件
    • 虚拟机自带的加载器
    • 启动类(根)加载器 BootstrapClassLoader
    • 扩展类加载器 ExtClassLoader
    • 应用程序加载器 AppClassLoader

4.双亲委派机制(安全)

  1. 类加载器收到类加载的请求
  2. 将这个请求向上委托给父类加载器去完成,一直向上委托,直到启动类加载;
  3. 启动加载器检查是否能够加载当前这个类,能够加载就结束,使用当前的类加载器,否则抛出异常,通知子加载器加载;
  4. 重复步骤3。

5.native

  1. 凡是带有native关键字的,说明java的作用范围达不到了,会去调用底层的C语言的库。 进入本地方法栈 ==> 调用本地方法接口 (Java Native Interface)
  2. JNI的作用: 扩展java的使用,融合不同的编程语言为java所用。
  3. 内存区域专门开辟了一块标识的区域: Native Method Stack 登记native的方法 。
  4. 在最终执行的时候,用JNI加载本地方法库。

6.PC寄存器(程序计数器)Program Counter Register

每一个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区的字节码,在执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。

7.方法区 Method Area

方法区是被所有线程共享,此区域属于共享区间。
静态变量、常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区中,但实例变量存在堆内存中,和方法区无关。

8.栈 stack

  1. 栈: 先进后出、后进先出。
    队列:先进先出(FIFO: First Input First Output)
  2. 栈内存,主管程序的运行,生命周期与线程同步;线程结束,栈内存也就是释放,对于栈来说,不存在垃圾回收
  3. 每个线程都包含一个栈区,保留基本数据类型,对象引用(reference),实例方法。
  4. 以栈帧为单位的压栈和出栈。

方法栈

9.堆 Heap

堆

  1. Heap,一个JVM只有一个堆内存,堆内存的大小是可以调节的。
  2. 类加载读取类文件后,一般会把类、方法、常量、变量,存储在堆内存中。保存我们所引用类型的真实对象。
  3. 新生区:类诞生和生长的地方,甚至死亡。
  4. 伊甸园区:所有对象都是在伊甸园区new出来的。
  5. 永久存储区:这个区域常驻内存,用来存放JDK自身携带的Class的对象,Interface元数据,存储的是Java运行时的一些环境和常量,这个区域不存在垃圾回收!关闭JVM虚拟机就会释放这个区域的内存。
  6. 一个启动类,加载了大量的第三方的jar包、Tomcat部署了太多的应用、大量生成的反射类,不断动态生成的反射类,不断被加载,直到内存满,就会出先OOM
    类加载过程

10.使用JProfile工具分析OOM原因

  1. 能够看到代码第几行错:内存快照分析工具,MAT,JProfiler
  2. MAT,JProfile作用:
    • 分析Dump内存文件,快速定位内存泄漏
    • 获得堆中的数据
    • 获得大对象
  3. JVM参数
    • -Xms:设置初始分配内存的大小 大约为总内存的1/64
    • -Xmx:设置最大分配内存 大约为总内存的1/4
    • –XX:+PrintGCDetails 打印GC垃圾回收信息
    • –XX:+HeapDumpOnOutOfMemoryError 打印出OOM Dump

11.垃圾回收机制 GC

  1. GC分为Minor GC和 Full GC。Minor GC清除Eden和from,转到to中。接下来from和to转换。继续清除Eden和from区;Full GC 搜集整个堆,包括新生代,老年代,永久代(在JDK 1.8及以后,永久代会被移除,换为metaspace)等收集所有部分的模式。
  2. GC算法:标记清除法、标记整理法、复制算法、引用计数法。
  3. 复制算法:将内存容量划分为两个大小相等的内存块,每次只使用一个,当这个容量快用完了。就将存活的对象复制到另一个上面区,然后把已经使用过的内存空间全部清理。
  • 使用场景:对象存活较低的内存空间,如Eden区。
  • 优点:内存分配不用考虑碎片等复制情况。
  • 缺点:空间利用率低;复制算法在对象存活率较高时就要进行较多的复制操作,效率会变低。
  1. 标记清除算法:算法分为标记和清除两个阶段:首先标记出需要被回收的对象,在标记完成后统一回收所有被标记的对象
  • 使用场景:使用于老年代。因为老年代回收的几率小且不频繁能减少内存碎片。
  • 缺点:标记和清除两个过程效率都不高;会产生大量不连续的内存碎片。
  1. 标记整理法:它的标记阶段和标记清除算法中的一样。整理阶段是将所有存活的对象压缩到内存的一端,最后清理边界外所有的空间。
  2. 总结:
    • 效率:复制算法 > 标记整理算法 > 标记清除算法
    • 内存利用率:标记整理算法 = 标记清除算法 > 复制算法
    • 内存整齐度:复制算法 = 标记整理法 > 标记清除法

12.JMM Java Memory Model

  1. Java的并发采用的是共享内存模型
  2. 作用:缓存一致性协议,用于定义数据读写的规则。
  3. JMM对这八种指令的使用,制定了如下规则:
    (1)不允许read和load、store和write操作之一单独出现。即使用了read必须load,使用了store必须write;
    (2)不允许线程丢弃他最近的assign操作,即工作变量的数据改变了之后,必须告知主存;
    (3)不允许一个线程将没有assign的数据从工作内存同步回主内存;
    (4)一个新的变量必须在主内存中诞生,不允许工作内存直接使用一个未被初始化的变量。就是怼变量实施use、store操作之前,必须经过assign和load操作;
    (5)一个变量同一时间只有一个线程能对其进行lock。多次lock后,必须执行相同次数的unlock才能解锁;
    (6)如果对一个变量进行lock操作,会清空所有工作内存中此变量的值,在执行引擎使用这个变量前,必须重新load或assign操作初始化变量的值;
    (7)如果一个变量没有被lock,就不能对其进行unlock操作。也不能unlock一个被其他线程锁住的变量;
    (8)对一个变量进行unlock操作之前,必须把此变量同步回主内存。

猜你喜欢

转载自blog.csdn.net/Zmd_23/article/details/108350672