1.JVM的位置
2.JVM体系结构
3.类加载器作用:加载Class文件
根加载器Root(最终执行)扩展加载器EXC应用加载器APP自定义加载器
4.双亲委派机制
1 类模板通过类装载器,然后类加载器收到类加载的请求,
2 将这个请求向上委托给父类加载器取完成,一直向上委托,直到启动类加载器
3 启动类加载器检查是否能够加载当前这个类,能加载就结束,使用当前加载器,否则,抛出异常,通知子类加载器
4 重复步骤3
5.组成沙箱的基本条件
字节码验证器,确保语言规范类
加载器防止恶意代码(双亲委派机制),防止篡改类,将代码归入保护域
调用远程代码不安全,后来jdk1.0加入验证
再后来jdk给代码分组调用,每个分组加上权限
再到后面jdk1.6加入了保护域
6.native
带了native的关键字说明超出了java的作用范围,需要进入本地方法栈然后去找JNI本地方法接口,
JNI是为了拓展JAVA的使用,融合不同的编程语言,
因为在那时候C和C++的风头很大,java为了能调用他们的方法,
开辟了一块标记区域,Nativemethod Stack,
在最终执行的时候,加载本地方法库中的方法通过本地方法接口
7.方法区
方法区里面有常量池比如类模板加载进来,
静态变量还有方法都会进入方法区而对象则会进入堆,
类的对象引用进入栈,按照引用去堆里找数据,如果要拿字段的值,常量池优先
8.栈
先进后出,后进先出,栈:栈内存,主管程序的运行,生命周期和线程同步栈默认程序执行完,自动释放内存,不存在垃圾回收
栈帧:
栈满了 StackOverflowError 栈的引用可以有 8大类型+对象引用+实例方法
9.程序计数器
就是计数,会自动增加一块临时空间计算增长,计算完马上释放,占用少
10.JVM
三种常用JVMBEA JRockitIBM J9 VM我们学习的是HotSpot,,
11.堆
一个JVM一个堆 新生区 老年区 永久区jdk1.5分为这三个区,1.6永久区慢慢变小,1.7后没有永久区了,改为元空间常量池也从方法区到退化,到元空间
而且物理上不存在,逻辑上存在
当新生区满会发生轻GC清理内存,活下来的去养老区,当养老区满的时候会触发重GC,然后活下来的去永久存储区,都满了就会出现OOM
OOM解决办法: 1.提高内存上限 2.内存快照工具,MAT,Jprofiler,Debug代码
功能:
- 读取dump内存文件,定位内存泄露位置
- 获得大的对象,堆中数据
11.堆内存调优
Xms8m Xmm8m -XX:+PrintGCDetails
Xms 设置初始化内存分配大小 1/4
Xmx 设置最大分配内存 1/64
默认情况分配内存是电脑的1/4,初始化的内存是1/64
//dump内存文件
Xms8m Xmm8m -XX:+HeapDumpOnOutOfMemoryError
12.GC:垃圾回收
12.GC常用算法
引用计数法
对象没有引用就会被清除,计数器作为标记
复制算法
幸存区不停交换复制,留一个空的幸存区每一个对象经历了15次轻GC不死就会到老年区
好处:没有内存碎片
坏处:浪费了内存空间,多了一般空间永远是空to
极端情况:假设对象百分百存活整个考进幸存区to,工程量大
最佳使用场景:对象存活度较低的时候,即新生区
标记清除算法
优点:不需要额外空间
缺点:两次扫描,严重浪费时间,会产生内存碎片
标记压缩:再优化
标记清除压缩
先标记清除几次,再进 行压缩
13.总结
14.JMM(java内存模型)