1.JVM的位置
JVM安装在操作系统上。
2. JVM的体系结构
3.类加载器及双亲委派机制
1. 类加载器接收到类加载的请求
2. 将这个请求向上委托给父类加载器去完成,一直向上委托,直到根加载器
3.根加载器检查是否能够加载当前这个类,能加载就结束,否则抛出异常,通知子加载器进行加载
4.重复步骤3
4. native
- 凡是带了native关键字的,说明java的作用范围达不到了,会去调用底层C语言的库,会进入本地方法栈,调用本地方法接口JNI(java native interface)
- JNI作用:扩展java的使用,融合不同的语言为java所用。
- 它在内存区域中专门开辟了一块标记区域:Native Method Stack ,用来等级native方法
- 在最终执行的时候,通过JNI加载本地方法库中的方法
5.方法区
方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单说,所有定义的方法的信息都保存在该区域,此区域属于共享区间。
静态变量、常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区中,但是实例变量存在堆内存中,和方法区无关。
6. 栈
栈遵循先进后出原则
栈:栈内存主管程序的运行,生命周期和线程同步。线程结束,栈内存也就释放了,对于栈来说,不存在垃圾回收问题。
栈主要存储:8大基本类型、对象引用、实例的方法
7. 堆
Heap,一个JVM只有一个堆内存,堆内存的大小是可以调节的。
类加载器读取了类文件后,一般会把什么东西放到堆中? 类的具体实例,方法,常量,变量 ,保存我们所有引用类型的真实对象。
堆内存中又细分为三个区域:
- 新生区
- 养老区
- 元空间(JDK1.8之前叫永久存储区)
GC垃圾回收,主要是在新生区和养老区。
假设内存满了,就会报错,OOM。堆内存不够。
8. 堆内存的调优
//返回虚拟机试图使用的最大内存(单位:字节)long max = Runtime.getRuntime().maxMemory();//返回jvm的初始化总内存(单位:字节)long total = Runtime.getRuntime().totalMemory();
默认情况下:分配的总内存是电脑内存的1/4,初始化内存是电脑内存的1/64
调优步骤
1:尝试扩大堆内存。
-Xms1024m -Xmx1024m -XX:+printGCDetails
-Xms 设置初始化内存分配大小
-Xmx 设置最大分配内存
-XX:+printGCDetails: 打印GC垃圾回收信息
-XX:+HeapDumpOnOutOfMemoryError 打印堆内存溢出的Dump文件日志信息
2:通过JProfiler等工具 分析内存,看一下哪个地方出现了问题
9.常见的GC算法
标记清除法 、 标记压缩法 、复制算法 、引用计数法