类加载器
类加载器的种类
扩展类加载器
ext目录下
通过系统类加载器获取扩展类加载器
getParent()
系统类加载器
获取系统类加载器的方法:ClassLoader.getSystemClassLoader()
获取当前类的加载器
Demo.getClassLoader()
获取类加载路径
System.getProperty("java.class.path")
类加载器的作用
加载.class文件
将类信息存放到堆里
双亲委派机制
当类加载器接收到加载类的请求时,会将请求委托给父类加载器,依次向上委托,直至启动类加载器;当启动类加载器表示可以加载该类,则加载;否则抛出异常,并将该请求向下委托给子类加载器进行加载。重复上一个步骤直至某一个加载器可以加载请求类。
<b>Native</b>
是一个关键字,说明Java的作用范围达不到了,会去调用底层的C语言库
会<b>进入</b>本地方法栈
<b>调用</b>本地方法接口 JNI
JNI的作用:扩展Java的使用,融合不同的编程语言为java所用
在内存区域中专门开辟了一块标记区域:本地方法栈,等级native方法
在最终执行的时候,通过JNI<b>加载</b>本地方法库中的方法
PC寄存器
每一个线程私有一个PC寄存器,指向方法中的方法字节码,存储下一条指令的地址
Java栈
先进后出
栈帧
一个线程私有一个Java栈,私有一个PC寄存器
栈+堆+方法区的关系
栈里存放的引用变量指向存放在堆里的真正实例对象;而常量池存放在方法区里,实例对象和常量池会有一个指向关系
堆
三种JVM
Sun的HotSpot
java -version
BEA的JRockit
IBM的J9 VM
一个内存只有一个堆
存放new 对象的地方
划分为三个区域
新生区
Eden区
幸存区0区
幸存区1区
存在垃圾回收---轻GC
元空间
错误
OOM :OutOfMemoryError
定位错误
首先通过调节内存大小查看是否是内存大小问题
然后通过专业工具定位错误代码
MAT
Jprofiler
StackOverFlow
调优
-Xms设置<b>堆的</b>初始化内存大小
默认为内存的1/64
-Xmx设置<b>堆的</b>可获取的最大内存
默认为内存的1/4
-XX :+PrintGCDetails打印GC信息
-Xx:+HeapDumpOnOutOfMemoryError
获取虚拟机内存的初始值
Runtime.getRuntime().totalMemory()
获取虚拟机内存的最大值
Runtime.getRuntime().maxMemory()
GC算法
引用计数器(不常用)
对新生区的每个对象都分配一个计数器,然后记录对象使用次数,回收使用次数为0的对象完成垃圾回收
复制算法
不是很明白为什么主要在新生区使用复制算法
将Eden存活的对象复制到幸存To区,然后清除Eden的对象;同时也将幸存From的对象复制到To区,然后清空From区,同时From区就变成了To区。
To区就是谁空谁是To区
优点:不会存在内存碎片问题
缺点:会导致一半的内存空间浪费(To区)
标记清除法
对Eden区的对象进行扫描,对或者的对象进行标记;然后对移动到幸存区的对象再次进行扫描,对活着的对象进行标记,没有被标志的需要清除
<b>优点:不需要额外空间??</b>
缺点:存在内存碎片
<b>疑惑:还有幸存0,1区么?幸存区的垃圾回收时间和幸存区的垃圾回收时间点一致么?</b>
标记压缩
在标记清除的基础上再优化:对内存进行压缩
消除内存碎片
压缩:就是对零散的对象进行排序
JMM
是规则、协议
定义了线程工作内存和主内存之间的抽象关系;线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存,由于线程之间的不可见性,可能会导致共享数据的不一致。
作用:缓存一致性协议,用于定义数据读写的规则
java memory model