当前位置: 首页 > news >正文 116.Java深入学习之JVM二 news 2026/5/12 16:42:37 116.Java深入学习之JVM二 今天整理的内容为 直接内存和垃圾回收 直接内存 正常来说需要一步一步才能访问到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 wf = new WeakReference(obj); 虚引用 其引用的对象被回收后 其会被先放入队列中 随后被回收(未被强引用引用) 终结器引用 用来追踪并把实现 finalize() 的对象放入终结器队列,等其 finalize 方法执行完后再由 GC 释放其内存上述五种引用我们来关联垃圾回收验证其内存溢出问题: 验证强引用-软引用内存溢出问题: public class Ying_yong {static final int _4MB = 4 * 1024 * 1024;public static void main(String[] args) {//强引用ArrayList<byte[]> list = new ArrayList<>();for (int i = 0; i < 5; i++) {list.add(new byte[_4MB]);} // soft();}//软引用 内存不足后 触发GC回收掉了public static void soft() {ArrayList<SoftReference<byte[]>> list = new ArrayList<>();for (int i = 0; i < 5; i++) {SoftReference<byte[]> sf = new SoftReference<>(new byte[_4MB]);list.add(sf);}for (SoftReference<byte[]> softReference : list) {System.out.println(softReference.get());}} } 注:我们设置堆大小20M 首先运行强引用 内存溢出 垃圾回收未触发 运行软引用 触发了GC垃圾回收 并打印出了东西 前面几个对象已经被回收掉了 2.垃圾回收算法 标记-清除 标记存活的对象(即GC Roots搜索到的对象) 清除掉未被标记(即可回收)的对象 速度效率很快 但是缺点在于内存空间造成不连续大量碎片 这个很简单理解 GC Roots标记存活对象 没被标记的即可回收的对象 被回收 标记-整理 所有存活对象向一侧移动 然后移动的时候清理掉可回收的对象 速度效率慢 但是整体紧凑 不会出现大量碎片空间 复制 分成两块内存大小一样 然后将第一块标记好的存活对象复制到第二块 清除掉第一块只剩下的可回收对象 交换以此反复 缺点就是占用双倍内存空间 也不会造成内存碎片 至于from区和to区是举例用的 后面分代回收会着重讲 接下来是重点即分代回收 首先分为新生代(年轻代)和老年代 新生代存放新创建的对象 采用复制算法 Minor GC 老年代存放多次使用存活时间长的对象 采用标记-清除/整理 算法 Full GC 分代回收的过程在复制算法讲过就是如下: 首先将eden和from区可存活的对象放入to区 年龄+1 若对象寿命达到阈值则移到老年代 然后清空eden和from区可回收的垃圾 交换from和to区 以此反复 大部分时间只会进行 Minor GC 只有内存极端不足或老年代对象占用过多时才触发 Full GC Minor GC 通过复制算法快速清理大部分垃圾,避免了 Full GC 的开销 Full GC 只在必要时才触发,采用 mark‑compact(标记‑压缩)以解决老年代碎片问题 我们当然需要代码实际中来验证: public class Test_GC_options {static final int _7MB = 7 * 1024 * 1024;static final int _10MB = 10 * 1024 * 1024;public static void main(String[] args) {} } 加入参数 打印参数观察 堆大小20M 新生代10M 单线程垃圾收集器 打印GC基础信息 -Xms20m -Xmx20m -Xmn10m -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc 不加入任何对象 运行 我们拿出来打印信息Heap堆def new generation新生代 我们设置的10M total 9216K, used 2352K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)eden space 8192K, 28% used [0x00000000fec00000, 0x00000000fee4c010, 0x00000000ff400000)from space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) to space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)tenured generation 老年代 10M total 10240K, used 0K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)the space 10240K, 0% used [0x00000000ff600000, 0x00000000ff600000, 0x00000000ff600200, 0x0000000100000000) Metaspace 元空间 used 579K, committed 768K, reserved 1114112K class space used 36K, committed 128K, reserved 1048576K 我们发现eden区已经用了28% 这个时候我们强引用加入存活对象 看变化 ArrayList<byte[]> list = new ArrayList<>();list.add(new byte[_7MB]); 加入7M后 因为eden区不够了 放入了from区 实际上是放到了to区 然后from区和to区互换了 这个时候我们在加入10M 这个时候新生代肯定顶不住了 list.add(new byte[_10MB]); 首先肯定溢出了 总共才20M 然后我们发现新生代不够了 就放入了老年代 至此验证完毕 3.GC参数和垃圾收集器 关于GC参数大概就是jvm的设置参数 我记得的: -Xms 初始堆大小 -Xmx堆最大大小 两个设为相同 避免运行时扩容带来的停顿 -Xmn 新生代大小 -XX:+PrintGCDetails -verbose:gc 打印详细GC信息 基础GC打印 -XX:+UseSerialGC 单线程垃圾收集器 更多参考:https://pdai.tech/md/java/jvm/java-jvm-param.html 1.串行垃圾回收器Serial(复制算法) Serial Old(标记-整理算法) -XX:+UseSerialGC 只使用一个线程进行垃圾回收工作 前者工作于新生代 后者老年代 2.吞吐量优先垃圾回收器 -XX:+UseParallelGC 大多数jdk8+版本默认并行GC 并行多线程工作 3.响应时间优先处理器 CMS 收集器 XX:+UseConcMarkSweepGC 采用标记-清除算法 JDK18+已移除 四个阶段 初始标记: 仅仅只是标记一下 GC Roots 能直接关联到的对象 速度很快 需要停顿 并发标记: 进行 GC Roots Tracing 的过程 它在整个回收过程中耗时最长 不需要停顿 重新标记: 为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录 需要停顿 并发清除: 不需要停顿 这里还需要介绍一个G1(Garbage-First): 首先我们需要区别一个东西 一中总结的GC(1)表示的这次GC的序号 而不是接下来我们要说的G1 核心就是:把堆划分为若干相等大小的Region (整体标记-整理算法实现 局部(两个Region之间)复制算法实现) 关于每个Region区 过程类似分代回收但也有区别 1.先在Young Region对象分配 达到阈值分配到老年代 触发Minor GC 2.若老年代也达到阈值就触发并发标记 3.有条件性的垃圾回收 另外插一嘴:大小达到甚至超过分区大小一半的对象称为巨型对象 GC会把它直接放进老年代 可减少(新生代处理时)停顿 4.GC调优 我就说俩问题 具体调优不是一成不变的 会根据环境和机器的情况调整 【新生代是否越大越好吗 不一定 可能会导致新生代的Minor GC停顿时间变长 若晋升率过高可能触发更多的Full GC Full GC和Minor GC频繁 空间内存不足导致 解决方案均衡新生代和老年代大小比例】 更多调优参考:https://pdai.tech/md/java/jvm/java-jvm-oom.html 查看全文 http://www.jsqmd.com/news/69278/ 相关文章: 中小企业走向境外资本市场:境外上市辅导、美股上市实践与中国境外券商投行机构角色——以顺安资本为例 解码生命蓝图,预见健康未来:北京守嘉健康基因检测业务介绍 day30-AgentRag应用开发 开放式互联互通的路上,希望畅联云越走越顺 第五十八篇 第五十七篇 2025年12月佛山二手房拍卖机构标杆推荐:佛山房屋拍卖推荐佛山市中正易拍拍卖有限公司 洛谷 P1203 [USACO1.1] 坏掉的项链 Broken Necklace 题解 最短代码|详细 【纯干货分享】计算机毕业设计必看必学(springboot二手车租赁管理专业的系统)原创的定制软件,java、PHP、python、C#小程序、文案全套、毕设程序定制/毕设成品等等. 2025年唐老狮:游戏开发教育商业模式深度解析与性价比评估 2025年12月东营搬家公司推荐:双福搬家,东营搬家搬厂、东营河口搬家、东营垦利搬家、东营市搬家、东营单位搬家、东营设备搬运、全场景搬迁服务标杆 2025年唐老狮全面盘点:游戏开发课的行业积淀与服务价值 2025年12月河南驻马店气体配送优质厂家推荐:河南宏源气体,氧气气体配送、氮气气体配送、氦气气体厂家、二氧化碳气体配送、氩气气体公司、高纯气体配送、多品类气体供应新标杆 2025年唐老狮:游戏开发教育领域深度解析与行业竞争力权威揭秘 吴恩达深度学习课程四:计算机视觉 第一周:卷积基础知识(二)卷积参数 day29-RAG实操 2025年唐老狮:游戏开发课程体系全景解析与行业应用价值深度评估 您的能源预算,是否正被“异常气温”悄悄透支?智慧气象助力实现精准能耗管理 - 教程 2025年唐老狮:游戏开发教学领域的深度解析与行业影响力权威评估报告 2025年法式高端家具TOP10榜(东莞深圳广州惠州专向版) 链路追踪基础SkyWalking/Zipkin认知与分布式系统问题定位实战 2025年12月多光谱相机厂家推荐,多光谱成像仪、高光谱成像系统、小型多光谱相机、微型多光谱相机、机载多光谱相机、便携多光谱相机、聚焦遥感测绘领域专业解决方案 2025年热门的国标止水钢板高评价厂家推荐榜 day16-Trae开发飞机大战并上线 2025年唐老狮深度解析:游戏开发课的实效教学逻辑 2025年12月阳光房遮阳棚优质厂家推荐,电动凉亭遮阳棚、防风帘遮阳棚、防蚊帘遮阳棚、小型遮雨棚、移动遮雨棚、金属遮雨棚、聚焦舒适节能解锁惬意户外空间 java 多线程deubg调试 day14-影刀获取抖音评论-微信自动发消息 2025年12月安检门厂家推荐:广东中安技术,手机安检门、贵金属安检门、探铜安检门、高精度安检门、半导体芯片安检门、多场景精准安检解决方案领航者 2025短片产业“效率革命”,AI如何让编剧摆脱“无效内卷”?