JVM学习笔记
1.JVM的位置:
电脑最底层是硬件包括(intel,Spac…等) 中间是 *** 作系统包括(Window,Linux,Mac等) 最上面是软件层,JRE和众多软件在这一层并列,JVM被包含于JRE里面 运行的java程序在JVM之上运行
2.JVM体系结构
3.类加载器
作用:加载Class文件 ~new class_name();
new 出来的是具体的实例。
类加载器分类:1.虚拟程序加载器;2.启动类(根)加载器;3.扩展类加载器;4.应用程序加载器
类加载器寻找类的步骤:启动类(根)加载器 ------> 扩展类加载器(安全) ------> 当前应用程序加载器
双亲委派机制:1.类加载器收到类加载的请求;2.将这个请求委托给父类加载器去完成,一直向上委托,直到启动类加载器;3.启动加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则,抛出异常,通知子加载器进行加载;4.重复步骤3 。
4.沙箱
所谓沙箱机制,便是基于双亲委派机制给java类加载带来的一个安全机制。 我们尝试去碰瓷原生api失败,是因为引导类加载器在加载的过程中会先加载jdk自带的文件。 我们尝试直接在java lang包下添加内容,结果直接报错,这也是沙箱安全机制的一种体现方式。
5.native
凡是带了native关键字的,说明Java的作用范围达不到了,会去调用C语言的库!会进入本地方法栈。调用本地方法接口 JNI
JNI的作用:扩展Java的使用,融合不同的编程语言为Java所用! 最初:C,C++。Java诞生会想要立足必须调用其的程序。它在内存区域中专门开辟了一块标记区域:native method stack ,登记native方法。
在最终执行的时候,加载本地方法库中的方法通过JNI。
现在调用其他接口: socket ,webservice,http…
6.方法区:
静态变量、常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区中,但是实例变量存在堆内存中,和方法区无关
7.PC寄存器(了解)
PC寄存器用来存储下一条指令的地址,也即将要执行的指令代码。由执行引擎读取下一条指令。
8.栈:数据结构 相对于队列
程序=数据结构+算法
栈:栈内存,主管程序的运行,生命周期和线程同步,线程结束,栈内存也就释放了,对于栈来说,不存在垃圾回收问题
栈:8大基本类型+对象应用+实例的方法
栈运行的原理:栈帧
9.三种JVM
Sun公司 HotSpot (重点)
BEA公司 JRockit
IBM
10.堆 Heap
一个JVM只有一个堆内存,堆内存的大小可以调节的;
类加载器读取了类文件后,一般把什么东西放在堆中? 类,方法,常量,变量~,保存我们所用引用类型的真实对象,就是实例。
堆内存中还要分为三个区域 轻GC表示轻回收,重GC表示重回收(full GC), GC垃圾回收主要在伊甸园区和养老区
新生区 Yong/New 类:诞生和成长的地方,甚至死亡。
伊甸园,所有的对象都是在这里 new 出来的;空间满了会触发 轻GC
幸存者区,上面轻GC之后幸存的进入这里
养老区 Old 新生区淘汰的在这里
永久区 Perm 这个区域常驻内存的,用来存放JDK自身携带的Class对象。Interface元数据,存储的是Java运行时的一些环境或类信息,这个区域不存在垃圾回收。关闭虚拟机的时候就会释放这个区域的内存。
jdk 1.6之前:永久代,常量池是在方法区中;
jdk1.7 : 永久代,但是慢慢地退化了,去永久代,常量池在堆中
jdk1.8 之后:无永久代,常量池在元空间
OOM:一个启动类,加载了大量的第三方jar包;Tomcat部署了太多的应用面,大量动态生成的反射类;不断地被加载;直到内存满了,就会出现OOM。
假设内存 (新生区和养老区)满了,OOM(out of memery …),堆内存不够!表示程序已经很严重了
在JDK8以后,永久存储区改了一个名字 元空间;
方法区里面的那个是常量池,紫色部分是堆的一部分,但是叫做“非堆”。元空间在逻辑上存在,物理上不存在。
oom怎么解决?
1.尝试扩大堆内存看结果
2.分析内存,看一下哪个地方出现了问题(专业工具)
能够看见第几行出错:内存快照工具,MAT,Jprofiler
MAT,Jprofiler作用:
1.分析Dump内存文件,快速定位内存泄露;
(Dump文件是进程的内存镜像,可以把程序的执行状态通过调试器保存到dump文件中。主要是用来在系统中出现异常或者崩溃的时候来生成dump文件,然后用调试器进行调试,这样就可以把生产环境中的dmp文件拷贝到自己的开发机上,调试就可以找到程序出错的位置。)
2.获得堆中的数据
3.获得大的对象…
11.GC介绍
GC垃圾回收
JVM在进行垃圾回收的时候,并不是对这三个区域统一回收。大部分时候,回收都是新生代
新生区
幸存区 (from 和 to)
老年区
GC的两种类:轻GC(普通的GC),重GC(全局GC)
GC算法:
复制算法
好处:没有内存的碎片
坏处:浪费了内存空间:多了一半空间永远是空(to区)。
复制算法最佳使用场景:对象存活度较低的时候;新生区
引用计数法
给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器都为0的对象就是不再被使用的,垃圾收集器将回收该对象使用的内存。
标记清除法
优点:不需要额外的空间!
缺点:两次扫描,严重浪费时间,会产生内存碎片。
标记压缩
标记清除压缩
先标记几次,再压缩
GC算法总结
内存效率:复制算法>标记清除算法>标记压缩算法 (时间复杂度)
内存整齐度:复制算法=标记压缩法>标记清除算法
内存利用率:标记压缩算法=标记清除算法>复制算法
没有JVM最优算法,只有最合适的算法。------->GC:分代收集算法
12.JMM
什么是JMM? java内存模型
干嘛的? 官方、博客、对应的视频!
如何学习?
狂神说学习笔记而已,小白一个,有错误可以留言,谢谢!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)