直接内存这小节我们来介绍系统中常用的直接内存
直接内存简介我们先来介绍一下直接内存的定义:
- 直接内存不受JVM内存回收管理
- 直接内存是直接受管于系统的内存,不能被JVM所调配
- 直接内存通常用于NIO操作,用于数据缓冲区,其分配成本较高,但读写性能较高
package cn.itcast.jvm.t1.direct;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;/** * 演示 ByteBuffer 作用 */public class Demo1_9 {static final String FROM = "E:\\编程资料\\第三方教学视频\\youtube\\Getting Started with Spring Boot-sbPSjI4tt10.mp4";static final String TO = "E:\\a.mp4";static final int _1Mb = 1024 * 1024;public static void main(String[] args) {io(); // io 用时:1535.586957 1766.963399 1359.240226directBuffer(); // directBuffer 用时:479.295165 702.291454 562.56592}// directBuffer(直接内存读取数据)private static void directBuffer() {long start = System.nanoTime();try (FileChannel from = new FileInputStream(FROM).getChannel();FileChannel to = new FileOutputStream(TO).getChannel();) {ByteBuffer bb = ByteBuffer.allocateDirect(_1Mb);while (true) {int len = from.read(bb);if (len == -1) {break;}bb.flip();to.write(bb);bb.clear();}} catch (IOException e) {e.printStackTrace();}long end = System.nanoTime();System.out.println("directBuffer 用时:" + (end - start) / 1000_000.0);}// io(jvm正常读取数据)private static void io() {long start = System.nanoTime();try (FileInputStream from = new FileInputStream(FROM);FileOutputStream to = new FileOutputStream(TO);) {byte[] buf = new byte[_1Mb];while (true) {int len = from.read(buf);if (len == -1) {break;}to.write(buf, 0, len);}} catch (IOException e) {e.printStackTrace();}long end = System.nanoTime();System.out.println("io 用时:" + (end - start) / 1000_000.0);}}
我们可以明显看到directBuffer速度比IO读取快很多,那么究竟是怎么实现的我们可以分别给出两张图进行解释:
- JVM正常读取
文章插图
- 直接内存读取
文章插图
我们由上图可以得知:
- JVM正常读取需要先复制一份经过系统内存缓冲区,然后再复制一份才能进入到java文件中
- DirectMemory可以同时在系统内存和java堆内存中使用,我们只需要传入数据到直接内存中就可以直接读取调用
package cn.itcast.jvm.t1.direct;import java.nio.ByteBuffer;import java.util.ArrayList;import java.util.List;/** * 演示直接内存溢出 */public class Demo1_10 {static int _100Mb = 1024 * 1024 * 100;public static void main(String[] args) {List<ByteBuffer> list = new ArrayList<>();int i = 0;try {while (true) {// 这里设置一个大小为100mb的直接内存ByteBuffer byteBuffer = ByteBuffer.allocateDirect(_100Mb);list.add(byteBuffer);i++;}} finally {System.out.println(i);}// 方法区是jvm规范,jdk6 中对方法区的实现称为永久代//jdk8 对方法区的实现称为元空间}}
直接内存释放原理我们目前所使用的直接内存是DirectMemory:package cn.itcast.jvm.t1.direct;import java.io.IOException;import java.nio.ByteBuffer;/** * 我们查看内存管理需要到任务管理器里查看,因为该内存属于系统内存,不再属于jvm */public class Demo1_26 {static int _1Gb = 1024 * 1024 * 1024;// 我们使用debug模式调试public static void main(String[] args) throws IOException {// 我们使用byteBuffer来调取1G的内存使用// 我们开启项目后会看到一个内存为1G的java项目ByteBuffer byteBuffer = ByteBuffer.allocateDirect(_1Gb);System.out.println("分配完毕...");// 输入空格后开始进行系统的垃圾回收,这时byteBuffer被回收,我们会注意到内存为1G的项目结束System.in.read();System.out.println("开始释放...");byteBuffer = null;System.gc();System.in.read();}}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 【lwip】08-ARP协议一图笔记及源码实现
- 用一台笔记本电脑如何赚钱(笔记本电脑赚钱的办法)
- 小米笔记本Pro15增强版评测_小米笔记本Pro15增强版评测表现
- 笔记本电脑CF中烟雾头怎么调(win10cf新版本烟雾保护头怎么调)
- 笔记本电脑配置高低怎么区分(笔记本电脑看什么配置判断好坏)
- 四 【单片机入门】应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及中断的使用
- pytorch、paddlepaddle等环境搭建 深度学习环境搭建常用网址、conda/pip命令行整理
- 三十九 Java开发学习----SpringBoot整合mybatis
- 2023年圣诞节学习运有所提升的星座智慧多多成绩提升
- 电脑开不了机怎么办简单方法(笔记本电脑开不了机)