看视频:狂神说java

博客:https://blog.csdn.net/weixin_43122090/article/details/105093777?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171168818216800225578834%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171168818216800225578834&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-105093777-null-null.142^v100^pc_search_result_base5&utm_term=jvm&spm=1018.2226.3001.4187

http://t.csdnimg.cn/yd7B9

JVM种类(了解)

1、Sun公司hotspot(主流) (我们学习的都是基于这个)

2、BEA jrockit

3、IBM J9vm

JVM运行时数据区

为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

image-20240402205344582
  • JVM的内存划分(可以这么理解:栈负责运行,堆负责存储)
image-20240325105756715

一、方法区

静态变量、常量、类信息(构造方法、接口定义)、运行时常量池存在方法区,但是实例变量存在堆内存中,与方法区无关。

(也就是说,static,final,Class,常量池在方法区中,其他与方法区无关)

二、堆(heap)

1、一个JVM只有一个堆内存,堆内存的大小是可以调节的,是虚拟机管理的内存最大的一块

2、类加载器读取了类文件后,一般会把什么东西放到堆中?

  • 所有的对象实例以及数组都在堆上分配 (此内存区域的唯一目的就是存放对象实例)

3、堆内存中还要细分为三个区域:(分区的目的是为了更好的回收和分配内存

  • 新生区(伊甸园区,幸存者0区,幸存者1区)

  • 养老区

  • 永久区(JDK8以后,永久存储区改名为元空间

    永久区:这个区域常驻内存,用来存放jdk自身携带的class对象,interface元数据,存储的是java运行时的一些环境或类信息,这个区域不存在垃圾回收!关闭vm虚拟就会释放这个区域的内存。

4、GC垃圾回收,主要是在伊甸园区和养老区

5、如果内存满了,报错OOM,堆内存不够:java.lang.outofmemoryerror:java.heap.space

//OOM:

  • 尝试扩大堆内存看结果
  • 分析内存,看一下哪个地方出现了问题(借助专业工具JPofiler)

6、图示:(方法区中的一小块为常量池)

image-20240401095247649

7、在项目中出现了oom故障,该如何排除?

  • (最快)能够看到第几行出错:内存快照分析工具:MAT, Jprofiler
  • Debug, 一行行分析代码

8、修改VM Options参数:

image-20240402103855766

9、Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的java虚拟机都是按照可扩展来实现的(通过参数-Xmx和-Xms设定)

三、Java虚拟机栈

1、是线程私有的,生命周期与栈相同。

2、虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧[1] (Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

3、会在栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和OutOfMemoryError异常。

四、本地方法栈

Native(唬住面试官)

1、凡是带了native关键字的,说明java的作用范围达不到了,会去调用底层c语言的库!

2、会进入本地方法栈。

3、会调用本地方法接口(JNI)

4、JNI作用:扩展Java的使用,融合不同的编程语言为JAVA所用!最初:C、C++

五、程序计数器

1、每个线程都有一个独立的程序计数器,它是当前线程所执行的字节码的行号指示器。

2、该内存区域是唯一一个没有规定任何OutOfMemoryError情况的区域。

3、若线程执行的是本地(native)方法,这个计数器值则为空。

类加载器

一、作用

二、双亲委派机制

步骤

1、类加载器收到类加载的请求;

2、将这个请求向上委托给父类加载器去完成,一直向上委托,直到启动类加载器(APP-EXT-BOOT)

3、启动类加载器肩擦好是否能加载当前类,能加载就结束并使用当前类;否则,抛出异常,通知子加载器进行加载

4、重复步骤3

(若都找不到,则报错class not found)

三、沙箱机制(sandbox)

1、是什么

沙箱就是一个限制应用程序对系统资源的访问的运行环境。

2、应用

![image-20240329193722938](/Users/jungoat/Library/Application Support/typora-user-images/image-20240329193722938.png)

3、理解

image-20240329193755113

就像上面这个图一样,有两个正方形,相互是独立的,里面各自装着应用,第一个正方形里的应用和第二个正方形的应用互不影响

垃圾回收(GC)

1、gc的作用区域只有堆和方法区

2、Jvm在进行gc时,并不是对三个区域统一回收,大部分时候都是回收新生代

  • 新生代
  • 幸存区(form, to(谁空谁是to))
  • 老年区

3、gc两种:轻cg(普通gc),重gc(全局gc)

4、gc算法:

(对象存活判定算法:1、引用计数法 2、可达性分析法)

(垃圾收集算法(分代收集理论):1、标记-清除算法 2、标记-复制算法 3、标记-整理算法)

(gc分代收集理论)

  • 复制算法(新生代,所以幸存区会有一个空的)
  • 标记清除算法image-20240402111333201
  • 标记压缩算法(防止内存碎片产生)
  • 标记清除压缩算法
image-20240402112320606

JMM: Java Memory Model

java四大引用

内存泄漏