Haoyuan's blog Haoyuan's blog
首页
导航站
  • Java基础

    • Java基础
    • Java集合
    • Java反射
    • JavaJUC
    • JavaJVM
  • Java容器

    • JavaWeb
  • Java版本新特性

    • Java新特性
  • SQL 数据库

    • MySQL
    • Oracle
  • NoSQL 数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • ActiveMQ
    • RabbitMQ
    • RocketMQ
    • Kafka
  • 进阶服务

    • Nginx
  • Spring
  • Spring Boot
  • Spring Security
  • Spring Cloud
  • 设计模式
  • 算法
  • 知识
  • 管理

    • Maven
    • Git
  • 部署

    • Linux
    • Docker
    • Jenkins
    • Kubernetes
  • 进阶

    • TypeScript
  • 框架

    • React
    • Vue2
    • Vue3
  • 轮子工具
  • 项目工程
  • 友情链接
  • 本站

    • 分类
    • 标签
    • 归档
  • 我的

    • 收藏
    • 关于
留言区
GitHub (opens new window)

Somnus Haoyuan

Word is cheap, show me the code.
首页
导航站
  • Java基础

    • Java基础
    • Java集合
    • Java反射
    • JavaJUC
    • JavaJVM
  • Java容器

    • JavaWeb
  • Java版本新特性

    • Java新特性
  • SQL 数据库

    • MySQL
    • Oracle
  • NoSQL 数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • ActiveMQ
    • RabbitMQ
    • RocketMQ
    • Kafka
  • 进阶服务

    • Nginx
  • Spring
  • Spring Boot
  • Spring Security
  • Spring Cloud
  • 设计模式
  • 算法
  • 知识
  • 管理

    • Maven
    • Git
  • 部署

    • Linux
    • Docker
    • Jenkins
    • Kubernetes
  • 进阶

    • TypeScript
  • 框架

    • React
    • Vue2
    • Vue3
  • 轮子工具
  • 项目工程
  • 友情链接
  • 本站

    • 分类
    • 标签
    • 归档
  • 我的

    • 收藏
    • 关于
留言区
GitHub (opens new window)
  • Java 基础 - SE

  • Java 进阶 - SE

  • Java 集合 - Collection

  • Java 并发 - JUC

  • Java 容器 - Web

  • Java 底层 - JVM

    • JVM - Java体系结构
    • JVM - 类加载子系统
    • JVM - 运行时数据区概述及线程
    • JVM - 程序计数器
    • JVM - 虚拟机栈
    • JVM - 本地方法接口
    • JVM - 本地方法栈
    • JVM - 堆
    • JVM - 方法区
    • JVM - 对象实例化内存布局与访问定位
    • JVM - 直接内存
      • Direct Memory
      • 非直接缓存区和缓存区
      • 存在的问题
    • JVM - 执行引擎
    • JVM - StringTable字符串常量池
    • JVM - 垃圾回收概述
    • JVM - 垃圾回收相关算法
    • JVM - 垃圾回收相关概念
    • JVM - 垃圾回收器
    • JVM - Class文件结构
    • JVM - 字节码指令集与解析
    • JVM - 类的加载过程详解
    • JVM - 再谈类的加载器
    • JVM - 调优概述
    • JVM - 监控及诊断工具命令行
    • JVM - 监控及诊断工具GUI
    • JVM - 运行时参数
    • JVM - 分析GC日志
  • Java 版本 - 新特性

  • Java
  • Java 底层 - JVM
Haoyuan
2022-01-22
目录

JVM - 直接内存

  • Direct Memory
  • 非直接缓存区和缓存区
  • 存在的问题

# Direct Memory

不是虚拟机运行时数据区的一部分,也不是《Java 虚拟机规范》中定义的内存区域。

直接内存是在 Java 堆外的、直接向系统申请的内存区间。

来源于 NIO,通过存在堆中的 DirectByteBuffer 操作 Native 内存。

通常,访问直接内存的速度会优于 Java 堆。即读写性能高。

  • 因此出于性能考虑,读写频繁的场合可能会考虑使用直接内存
  • Java 的 NIO 库允许 Java 程序使用直接内存,用于数据缓冲区

使用下列代码,直接分配本地内存空间:

public class BufferTest {
    private static final int BUFFER = 1024 * 1024 * 1024; // 1GB
    
    public static void main(String[] args) {
		ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER); // 此时电脑的内存被该进程占用 1GB
    }
}
1
2
3
4
5
6
7

# 非直接缓存区和缓存区

原来采用 BIO 的架构,我们需要从用户态切换成内核态。

image-20200709170907611

NIO 的方式使用了缓存区的概念,可以看到,去掉了中间的两个地址空间,直接使用本地的物理内存

image-20220122233049383

# 存在的问题

也可能导致 OutofMemoryError 异常。

由于直接内存在 Java 堆外,因此它的大小不会直接受限于 -Xmx 指定的最大堆大小,但是系统内存是有限的,Java 堆和直接内存的总和依然受限于操作系统能给出的最大内存。

缺点:

  • 分配回收成本较高
  • 不受 JVM 内存回收管理

直接内存大小可以通过 MaxDirectMemorySize 设置。

如果不指定,默认与堆的最大值 -Xmx 参数值一致

image-20200709230647277

编辑此页 (opens new window)
#Java
更新时间: 2025/04/06, 01:04:59
JVM - 对象实例化内存布局与访问定位
JVM - 执行引擎

← JVM - 对象实例化内存布局与访问定位 JVM - 执行引擎→

最近更新
01
技术随笔 - Element Plus 修改包名 原创
11-02
02
Reactor - 扩展性
11-02
03
Reactor - 最佳实践
11-02
更多文章>
Theme by Vdoing | Copyright © 2021-2025 Somnus Haoyuan | MIT License
京公网安备 11010802034042号 京ICP备2025120692号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式