(个人对黑马程序员JVM完整教程总结,原视频地址https://www.bilibili.com/video/BV1yE411Z7AP)
直接内存 定义- 常见于NIO *** 作时,用于数据缓冲区(NIO(JDK1.4)模型是一种同步非阻塞IO)
- 分配回收成本较高,但读写性能高
- 不受 JVM 内存回收管理
原先存在 两块 缓冲区
读取的时候必然需要读取两次,将会造成不必要的复制,造成效率不高
分配直接内存后
这块 *** 作系统划出的内存,java代码可以直接访问(系统和java代码 可以共用这块区域)
大大提升速度
直接内存不受JVM内存管理,其分配和释放通过一个unsafe对象实现
且 不会自动回收 必须调用unsafe.freeMemory()来释放内存
-XX:+DisableExplicitGC 可以禁用 System.gc() 显式的垃圾回收,Full GC
会造成直接内存长时间无法被回收的问题,还是需要手动unsafe.freeMemory()来释放内存
垃圾回收 1、如何判断对象可以回收 可达性分析算法( JVM垃圾回收采用 )该算法首先要确定一系列 根 对象(肯定不能被回收的对象),
然后对 堆 中的所有对象进行扫描,如果有对象直接或间接的被 根 对象引用 (沿着GC Root对象为起点的引用链找到该对象),就不会被回收,反之则可以被垃圾回收。
哪些对象可以作为 根 对象系统类核心类对象, *** 作系统调用的对象,活动线程中局部变量的对象,加锁的对象
- 强引用
- 软引用
- 弱引用
- 虚引用
- 终结器引用
强引用:当A1对象被直接或间接强引用时,A1对象不会被回收
软引用:当A2对象没有被强引用时,只有软引用时,当垃圾回收时且内存还是不足时,A2对象会被回收
弱引用:当A3对象没有被强引用时,只有弱引用时,当垃圾回收时,A3对象一定会被回收
当 软引用 和 弱引用 的引用 对象被回收时,软引用 和 弱引用 可以进入(进入和不进入都可以) 引用队列,
因为软引用 和 弱引用 自身也占有一定内存,如果想要处理它们,可以在引用队列中去处理
虚引用:当对象没有被强引用时(主要配合ByteBuffer),虚引用所引用的对象被回收时,虚引用会进入引用队列,间接的由一个线程来调用虚引用中的方法Unsafe.freeMemory 来释放直接内存。
终结器引用:当A4对象没有被强引用时,当A4对象将要被垃圾回收时(还没被回收),会先将引用的终结器引用放入引用队列,由一条优先级很低的线程扫描,若扫描到终结器引用,它就会找到被引用的A4对象,并调用其finalize()方法,下次垃圾回收时,就可以将其真正回收。(效率很低,不推荐使用)
虚引用 和 终结器引用 都必须关联 引用队列
软引用 应用:
清除时并不会将字节清除,而是记录占用的起始和结尾地址,下次分配新对象时去这些地址中找并内存分配
优点:速度快(只需要标记地址)
缺点:容易产生 内存碎片
标记整理优点:解决内存碎片问题
缺点:整理使得效率变低(联系到地址改变)
复制
将FROM区中存活的对象 复制 到TO区中
之后 清空FROM中的垃圾,并 互换FROM 和 TO 的位置(FROM变TO,TO变FROM)
优点:不会产生碎片
缺点:占用双倍的内存
分带回收机制区域划分
该机制如何工作:
标记成功后,采用复制算法
将存活的对象 复制到 幸存区TO中 并且 将这些存活的对象 寿命 + 1
交换FROM 和 TO的位置(内存空间不变)
反复 Minor GC 之后,存活久的对象,当它的生命超过阈值,就可以晋升老年代中
Minor GC 会引发 stop the world,暂停其他用户的线程,等垃圾回收结束,用户线程才回复运行
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)