目录
- 一.JVM概述
- 1.jvm简介
- 2.jvm作用
- 3.jvm的内存模型
- 二.类加载器
- 1.类加载器的作用
- 2.加载器的类型
- 3.双亲委派机制的运行过程(面试题)
- 三.JVM内存模块
- 1.方法区
- 2.堆
- 3.栈(虚拟机栈)
- 4.栈(本地方法栈)
- 5.OutOfMemoryError内存溢出和StackOverFlowError栈溢出及解决方法(面试题)
- (1).OutOfMemoryError内存溢出(OOM)
- (2).StackOverFlowError栈溢出
- (3).idea配置jvm
- 6.程序计数器
一.JVM概述
1.jvm简介
JVM是Java Virtual
Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
2.jvm作用
Java中的所有类,必须被装载到JVM中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中。
3.jvm的内存模型
二.类加载器
1.类加载器的作用
将class字节码内容加载到内存中,并将这些静态数据转换成方法区运行时数据结构,然后在堆中形成代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口。
2.加载器的类型
引导类加载器(Bootstrap ClassLoader)
:用c++编写,是JVM自带的类加载器,负责java平台核心库,用来装载核心类库,该加载器无法直接获取;
拓展类加载器(ExtensionClassLoader)
:负责jre/lib/ext目录下的jar包或 -D java.ext.dirs 指定下的jar包装入工作库
系统类加载器(ApplicationClassLoader)
:负责java-classpath或者 -D java.class.path所指的目录下的类与jar包装入工作,是最常用的加载器
自定义类加载器(Custom ClassLoader)
:由开发人员自己定义。
3.双亲委派机制的运行过程(面试题)
①.类加载器收到类加载的请求
②.将这个请求委托给父类加载器去完成,一直向上委托,直到启动类加载器
③.引导类加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则,抛出异常,通知子加载器进行加载,向下加载。
④.重复步骤③。
双亲委派机制能够保证多加载器加载某个类时,最终都是由一个加载器加载,确保最终加载结果相同。
三.JVM内存模块
1.方法区
方法区存储的是:static、final、常量池、常量池以及一些类和方法信息
2.堆
概念:堆是线程共享的内存区域,它是虚拟机管理内存中最大的一块。
堆储存的是:实例对象
堆的具体示意图(jdk8及之后)
GC主要在新生区(伊甸园区)、老年区
新生区(伊甸园区(对象都是在这个区new出来的)、幸存区to、幸存区from:幸存区位置会互相交换,谁空谁是to)
老年区
永久区:存储的是java的运行环境或类信息,这个区域不存在垃圾回收,关闭jvm就会释放内存
一个启动类加载大量的jar包。tomcat部署太多应用。内存满了就oom
jdk1.6之前:永久代,常量池是在方法区
jdk1.7去永久代,常量池在堆中
jdk1.8之后:无永久代,常量池在元空间中
3.栈(虚拟机栈)
概念:又名堆栈,主管程序运行,生命周期和线程同步,线程结束,栈内存就释放了。不存在垃圾回收问题。
虚拟机栈储存的是:8大基本类型 + 对象引用 + 实例方法
栈的具体示意图
4.栈(本地方法栈)
不论是内存溢出还是栈溢出,简单来说就是你放的太多了空间不够了,溢出来了,这样就比较好理解了。
本地方法栈储存的是:本地接口库里调用的方法,就是java里面
native
关键字修饰的方法。
凡是带native关键字的,说明java的作用范围达不到了,回去调用底层c/c++语言的库,首先会进入本地方法栈,然后到本地方法接口
5.OutOfMemoryError内存溢出和StackOverFlowError栈溢出及解决方法(面试题)
(1).OutOfMemoryError内存溢出(OOM)
原因:①是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于能提供的最大内存。
②由于长期保持某些资源的引用,垃圾回收器无法回收它,从而使该资源不能够及时释放,也称为内存泄露。
解决:①设置JVM的堆参数( -Xmx:JVM最大内存 -Xms:启动初始内存 -Xmn:新生代大小 -Xss:每个线程虚拟机栈及堆栈的大小 ) 例如:
-Xms1024m -Xmx1024m -Xmn512m -Xss5m
。
②分析内存,看一下那个地方出现了问题(专业工具:Jprofiler,MAT)分析Dump内存文件, 快速定位内存泄漏,怎么查找dump文件,直接找到文件的文件夹打开获得大的对象。
制造堆溢出:一直死循环new对象就ok了。
- –Xms:JVM初始分配的堆内存,默认是物理内存的1/64。
- –Xmx:JVM最大允许分配的堆内存,默认是物理内存的1/4。
- –Xmn:堆内新生代的大小。通过这个值也可以得到老生代的大小:-Xmx减去-Xmn。
- –Xss:规定了每个线程虚拟机栈及堆栈的大小,一般情况下,256k是足够的,此配置将会影响此进程中并发线程数的大小。
- 更多JVM调优总结及命令
(2).StackOverFlowError栈溢出
原因:线程请求分配的栈容量超过Java虚拟机栈允许的最大容量。
解决:①修改代码 ②增加线程堆栈大小(-Xss)。
制造栈溢出:一直死循环调用方法就行。
(3).idea配置jvm
①配置某个项目
②全局配置
6.程序计数器
每个线程都有自己的程序计数器这样当线程执行切换的时候就可以在上次执行的基础上继续执行,是线程私有的,生命周期与线程的生命周期保持一致。