1.JVM的位置

JVM探究_java

2.jvm的体系结构

JVM探究_类加载器_02

99%的JVM调优都在堆中调优,java栈、本地方法栈、程序计数器不存在垃圾回收

3.类加载器

作用:加载.class文件

JVM探究_加载器_03

  1. 虚拟机自带的加载器
  2. 启动类(根)加载器 Bootstrap ClassLoader 加载jt.jar包中的类
  3. 扩展类加载器 Extension ClassLoader 加载ext文件夹下所有.jar包中的类
  4. 应用程序加载器 Application ClassLoader 加载自己写的类
4.双亲委派机制

双亲委派机制:安全

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

Class Not Found异常就是这么来的

5.沙箱安全机制

Java安全模型的核心就是Java沙箱(sandbox) ,

​ 什么是沙箱?沙箱是一个限制程序运行的环境。沙箱机制就是将Java代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本

地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。

沙箱主要限制系统资源访问,那系统资源包括什么? CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不

样。

所有的Java程序运行都可以指定沙箱,可以定制安全策略。

在Java中将执行程序分成本地代码和远程代码两种,本地代码默认视为可信任的,而远程代码则被看作是不受信的。对于授信的本地代

码,可以访问一切本地资源

6.Native
  • native :凡是带了native关键字的,说明java的作用范围达不到了,回去调用底层c语言的库!
  • 会进入本地方法栈
  • 调用本地方法本地接口 JNI (Java Native Interface)
  • JNI作用:开拓Java的使用,融合不同的编程语言为Java所用!最初: C、C++
  • Java诞生的时候C、C++横行,想要立足,必须要有调用C、C++的程序
  • 它在内存区域中专门开辟了一块标记区域: Native Method Stack,登记native方法
  • 在最终执行的时候,加载本地方法库中的方法通过JNI
  • 例如:Java程序驱动打印机,管理系统,掌握即可,在企业级应用比较少
  • private native void start0();
  • 调用其他接口:Socket. . WebService~. .http
7.PC寄存器

程序计数器: Program Counter Register

每个线程都有一个程序计数器,是线程私有的,就是一个指针, 指向方法区中的方法字节码(用来存储指向像一条指令的地址, 也即将要执

行的指令代码),在执行引擎读取下一条指令, 是一个非常小的内存空间,几乎可以忽略不计

8.方法区 method area

方法区是被所有线程共享的,所有的字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单说,所有定义方法

的信息都保存在该区域,此区域属于共享空间

存储内容:static、final、.class、常量池

9.栈 stack

栈:先进后出

队列:先进先出( FIFO : First Input First Output )

栈内存:主管程序的运行,生命周期和线程同步

线程结束,栈内存也就是释放,对于栈来说,不存在垃圾回收问题

一旦线程结束,栈就Over!

栈满了: StackOverflowError

存储:8大基本类型 + 对象引用 + 实例的方法

10.三种jvm
  1. HotSpot 我们用的

  2. JRockit BEA

  3. J9 vm IBM

11.堆 heap

Heap,一个JVM只有一个堆内存,堆内存的大小是可以调节的。

堆内存划分:

  • 新生区(New):伊甸园(Eden)、幸存0区(from)、幸存1区(to)。对象在这里诞生、成长、甚至死亡

    • 伊甸园(Eden):所有对象都是在Eden区new出来的。
  • 老年区(Old):

  • 永久区(Perm):jdk1.8以后,叫元空间(方法区在这里,常量池在方法区里)。这个区域是常驻内存的,用来存放jdk自身携带的

class对象。

伊甸园满了就触发轻GC,经过轻GC存活下来的就到了幸存者区,幸存者区满之后意味着新生区也满了,则触发重GC,经过重GC之后

存活下来的就到了养老区。

堆内存满了:OutOfMemoryError

12.堆内存调优

OOM:

  • 尝试扩大堆内存看结果

  • 分析内存,看一下哪个地方出了问题(专业工具)

Xms1024m Xmx1024m -XX:+PrintGCDetails

在一个项目中,突然出现了OOM故障,那么该如何排除?研究为什么出错

jprofiler作用:

  • 分析dump内存文件,快速定位内存泄露

  • 获得堆中的数据

  • 获得大的对象

13.GC

轻GC

重GC

引用计数法:记录每个对象的引用次数,长时间没有被引用的对象就被清除掉。

复制算法:
JVM探究_堆内存_04
JVM探究_java_05
好处:没有内存碎片

坏处:浪费内存空间,多了一半to空间永远是空的。

复制算法最佳使用场景:对象存活度较低的时候 -> 新生区

标记清除算法:
JVM探究_类加载器_06
优点:不需要额外的空间。

缺点:两次扫描,严重浪费时间,会产生内存碎片。

标记压缩:

标记 -> 清除 -> 压缩