JVM(HotSpot):直接内存及其使用建议

devtools/2024/10/21 23:34:44/

文章目录

  • 一、什么是直接内存?
  • 二、特点
  • 三、使用案例
  • 四、直接内存的管理

一、什么是直接内存?

Direct Memory:系统内存

普通IO,运行原理图
磁盘到系统内存,系统内存到jvm内存。
在这里插入图片描述
NIO,运行原理图
划分了一块区域,JVM和系统共享的内存区间,这样,就减少了一次IO操作。
在这里插入图片描述

二、特点

常见于 NIO 操作时,用于数据缓冲区
分配回收成本较高,但读写性能高
不受 JVM 内存回收管理

所以,我们可以在IO程序中,使用直接内存来优化程序的读写性能。

三、使用案例

关键代码:ByteBuffer.allocateDirect(_1Mb);

public class Demo1_9 {static final String FROM = "E:\\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}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);}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);}
}

但是,直接内存,是不受JVM管理的
另外,我们显示调用gcJVM也不是立马就执行gc

而且,一般我们会在项目中禁用显示调用gc,因为,Full GC影响性能。
禁用参数:-XX:+DisableExplicitGC

四、直接内存的管理

底层是如何回收直接内存的?

  • 使用了 Unsafe 对象完成直接内存的分配回收,并且回收需要主动调用 freeMemory 方法
  • ByteBuffer 的实现类内部,使用了 Cleaner (虚引用)来监测 ByteBuffer 对象,一旦
    ByteBuffer 对象被垃圾回收,那么就会由 ReferenceHandler 线程通过 Cleanerclean 方法调
    freeMemory 来释放直接内存
    在这里插入图片描述
    我们知道,不建议程序员显示调用gc,来回收JVM对象。
    但是,等待JVM自主的Full GC,又是不确定的。
    所以,还是,建议我们自己手动回收直接内存。
public class Demo1_27 {static int _1Gb = 1024 * 1024 * 1024;public static void main(String[] args) throws IOException {Unsafe unsafe = getUnsafe();// 分配内存long base = unsafe.allocateMemory(_1Gb);unsafe.setMemory(base, _1Gb, (byte) 0);System.in.read();// 释放内存unsafe.freeMemory(base);System.in.read();}public static Unsafe getUnsafe() {try {Field f = Unsafe.class.getDeclaredField("theUnsafe");f.setAccessible(true);Unsafe unsafe = (Unsafe) f.get(null);return unsafe;} catch (NoSuchFieldException | IllegalAccessException e) {throw new RuntimeException(e);}}
}

http://www.ppmy.cn/devtools/127683.html

相关文章

spdlog学习记录

spdlog Loggers:是 Spdlog 最基本的组件,负责记录日志消息。在 Spdlog 中,一个 Logger 对象代表着一个日志记录器,应用程序可以使用 Logger 对象记录不同级别的日志消息Sinks:决定了日志消息的输出位置。在 Spdlog 中&…

01-编程入门

文章目录 Python学习方向什么是编程语言编程语言发展史Python环境安装 Python学习方向 爬虫工程师 ​ 爬虫-模拟用户向服务器发送请求–》爬取数据 ​ 1.娱乐数据、商业数据、付费数据。 ​ 2.搜索引擎(百度、谷歌、搜狗,以及一些小网站内的搜索迎引擎&a…

windows免密ssh登录Linux

1.winr打开运行---- 输入:cmd(命令提示符) 查看系统是否自带openssh ssh -V 2.生成公钥私钥文件 ssh-keygen 3.进入秘钥存放目录 cd C:\Users\admin/.ssh/#查看秘钥文件 dir 4.将公钥文件长传至Linux服务器 scp .\id_rsa.pub root20.20.…

mysql设置远程连接

要使MySQL支持远程连接,需要进行以下操作: 修改MySQL配置文件(通常是my.cn.cnf或my.ini),注释掉bind-address这一行,或者将其值设置为0.0.0.0,这样MySQL就能监听所有网络接口。 进入以下目录 …

互联网语言 互联网开发 互联网架构

JAVA和PHP是两种广泛应用于互联网开发的编程语言,它们在多个维度上展现出显著的不同。 JAVA是一种面向对象的编程语言,以其严谨、高效的特性而著称。JAVA的语法结构复杂且规范,强调封装、继承和多态等面向对象原则,适合构建大型企…

对BSV区块链下一代节点Teranode的答疑解惑(下篇)

​​发表时间:2024年8月7日 2024年初BSV区块链研发团队揭晓了即将到来的Teranode更新的突破性特性,这些特性将显著提升网络的效率和处理速度,使BSV区块链能够达到百万级TPS。 Teranode的项目主管Siggi Oskarsson强调:“当你阅读这…

2024JAVA面试题

一、JAVA基础 1、面向对象的三个基本特征? 面向对象的三个基本特征是:封装、继承和多态。 封装:隐藏部分对象的属性和实现细节,对数据的访问只能通过外公开的接口。通过这种方式,对象对内部数据提供了不同级别的保护…

RFC2616 超文本传输协议 HTTP/1.1

一、URL-俗称“网址” HTTP 使用 URL(Uniform Resource Locator,统一资源定位符)来定位资源,它是 URI(Uniform Resource Identifier,统一资源标识符)的子集,URL 在 URI 的基础上增加了定位能力 URI 除了包含 URL,还包…