今天整理的内容为 直接内存和垃圾回收
直接内存

正常来说需要一步一步才能访问到jvm的堆内存
但是直接内存:
过 java.nio(java I/O库)直接缓冲区直接分配
绕过堆,由操作系统直接管理的本地内存区域,主要用于提升高性能I/O操作的速度
回收成本高不受JVM内存回收管理 读写性能高
这样就可以直接访问jvm的堆内存
其语句为:
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(); 开辟分配直接内存
同样这样也会造成内存溢出问题
我们来验证其直接内存的过程原理:
public class 直接内存 {static int _1G = 1024 * 1024 * 1024;public static void main(String[] args) throws IOException {ByteBuffer byteBuffer = ByteBuffer.allocateDirect(_1G);System.out.println("分配");//等待用户输入EnterSystem.in.read();System.out.println("释放");//失去所有对直接缓冲区的引用byteBuffer = null;System.gc();System.in.read();}
}
大致就是看到直接内存如何分配和gc回收是否会释放掉它(注:我们需要在任务管理器中查看进程变化)
创建分配出来
然后gc回收 发现释放掉了
关于过程:
需要我们进入直接内存分配方法中
创建了DirectByteBuffer
对应关联了cleaner
然后GC触发后 就执行cleaner.run
UNSAFE.freeMemory释放直接内存
大致流程就是:
触发GC回收->DirectByteBuffer->关联Cleaner->Cleaner.run() UNSAFE.freeMemory->释放native堆上内存
垃圾回收
关于这个是重点也是难点 我尽量理解这样的

首先一个对象能不能回收JVM如何知道
1.引用计数算法 给对象添加一个引用计数器 引用失效减1 当变为0可被回收
但是如果两个对象循环引用 就永远不会为0 JVM不采用这个
2.可达性分析算法 从GC Roots 为开始点 然后搜索 能搜索到的对象都是存活的 不可搜索到的可被回收
JVM采用此算法 线程栈中的局部变量 静态字段(static) 锁(synchronized)/JNI、本地线程 ThreadLocal 上的值
可达性分析算法 就是从根开始找 找不到的对象就是不可存活对象 可回收掉
1.五种引用类型
- 强引用
new 对象(); 即为强引用
被强引用关联的对象不可被回收
之前关于字符串常量池那些整理也有
- 软引用
被软引用关联的对象 内存不足的情况下会被回收(也未被强引用引用)
SoftReference<对象> sf = new SoftReference<对象>(obj); - 弱引用
(未被强引用引用) 一定会被回收掉
WeakReference









