JVM 堆外内存详解
Java 进程内存占用除了JVM 运行时数据区,还有直接内存(Direct Memory)区域及 JVM 程序自身也会占用内存
- 直接内存(Direct Memory)区域:直接内存通过使用Native堆外内存来存储数据,这意味着数据不会被JVM的垃圾回收机制自动回收。与JVM堆内存相比,直接内存的分配和释放成本较高,因为它涉及与操作系统交互和内存管理的开销,也可能导致OOM异常出现
- JVM 程序自身:JVM本身是个本地程序,还需要其他的内存去完成各种基本任务,比如,JIT Compiler 在运行时对热点方法进行编译,就会将编译后的方法储存在 Code Cache 里面;GC 等功能需要运行在本地线程之中,类似部分都需要占用内存空间

JVM内存区域划分详见 Java 内存区域与内存溢出异常
堆外内存
JVM 的堆外内存是指分配在JVM堆之外的内存空间,它不受JVM的垃圾回收机制管理。 以下是几种常见的JVM堆外内存:
- 直接字节缓冲区(Direct ByteBuffers):Direct ByteBuffer是JVM堆外内存的一种形式,它通过使用Native堆外内存来存储数据。
- NIO(New I/O)内存映射文件(Memory-mapped Files):NIO提供了一种将文件映射到内存的方式,这种内存映射文件将文件的内容直接映射到堆外内存中,可以通过内存访问的方式来读写文件。
- JNI(Java Native Interface):JNI允许Java程序与本地代码进行交互,可以在本地代码中分配和管理堆外内存。
堆外内存可以使用Native Memory Tracking 或 Arthas memory 进行监控及诊断
直接字节缓冲区
在实际使用中,Java 会尽量对 Direct Buffer 仅做本地 IO 操作,对于很多大数据量的 IO 密集操作,可能会带来非常大的性能优势,因为:
- Direct Buffer 可以通过
ByteBuffer.allocateDirect()方法来创建,它的数据存储在堆外内存中,生命周期内内存地址都不会再发生更改,进而内核可以安全地对其进行访问,很多 IO 操作会很高效 - 减少了堆内对象存储的可能额外维护工作,所以访问效率可能有所提高
Direct Buffer 创建和销毁过程中,都会比一般的堆内 Buffer 增加部分开销,所以通常都建议用于长期使用、数据较大的场景。
可以使用JVM参数设定直接内存限制
-XX:MaxDirectMemorySize=512M
大多数垃圾收集过程中,都不会主动收集 Direct Buffer,它的垃圾收集过程,就是基于 Cleaner(一个内部实现)和幻象引用(PhantomReference)机制,其本身不是 public 类型,内部实现了一个 Deallocator 负责销毁的逻辑。对它的销毁往往要拖到full GC的时候,所以使用不当很容易导致OutOfMemoryError
Direct Buffer 回收方式:
- 在应用程序中,显式地调用
System.gc()来强制触发。 - 另外一种思路是,在大量使用 Direct Buffer 的部分框架中,框架会自己在程序中调用释放方法(Netty 就是这么做的,有兴趣可以参考其实现PlatformDependent0)
- 重复使用 Direct Buffer
NIO
Java NIO(New I/O)是Java提供的一套用于高效处理I/O操作的API,引入自JDK 1.4版本。相对于传统的Java I/O(IO流)API,Java NIO提供了更灵活、更高效的非阻塞I/O操作方式,适用于构建高性能的网络应用程序。
Java NIO的核心概念包括以下几个部分:
- 通道(Channel):通道是数据源和数据目标之间的连接,可以通过通道读取和写入数据。通道可以是双向的,可以从通道中读取数据,也可以向通道中写入数据
- 缓冲区(Buffer):缓冲区是一个固定大小的数据容器,用于存储读取和写入的数据。通过缓冲区可以更高效地读写数据,避免频繁的数据拷贝操作。缓冲区可以读取和写入不同类型的数据,如字节、字符、整数等
- 选择器(Selector):选择器是用于多路复用非阻塞I/O操作的组件。可以通过选择器同时管理多个通道,使得单线程可以处理多个通道的I/O操作,提高系统的性能和吞吐量
NIO提供了一种将文件映射到内存的方式,这种内存映射文件将文件的内容直接映射到堆外内存中。这种方式在处理大型文件时可以提供更高的性能和效率
JNI
使用JNI(Java Native Interface)可以在Java程序中通过调用本地代码来使用JVM堆外内存。JNI提供了一种机制,使得Java程序可以与本地代码进行交互,调用本地代码中的函数和访问本地内存
通过JNI,Java程序可以直接访问和操作本地内存,例如在C或C++中使用
malloc()和free()函数进行内存分配和释放
JNI操作JVM堆外内存具体步骤
- 定义本地方法:在Java类中声明本地方法,使用native关键字标记。
public class NativeMemoryExample {public native void allocateMemory(int size);public native void freeMemory();
}
- 生成本地方法的头文件:使用Java的javac命令编译Java源文件,然后使用javah命令生成本地方法的头文件。
javac NativeMemoryExample.java
javah NativeMemoryExample
这将生成名为NativeMemoryExample.h的头文件
- 实现本地方法:在本地代码中实现Java类中声明的本地方法。在本地方法中可以使用C/C++等编程语言来操作堆外内存
#include "NativeMemoryExample.h"
#include <stdlib.h>JNIEXPORT void JNICALL Java_NativeMemoryExample_allocateMemory(JNIEnv *env, jobject obj, jint size) {void *buffer = malloc(size);// 使用buffer进行堆外内存操作
}JNIEXPORT void JNICALL Java_NativeMemoryExample_freeMemory(JNIEnv *env, jobject obj) {// 释放之前分配的堆外内存free(buffer);
}
- 编译本地代码:使用C/C++编译器将本地代码编译为共享库(或动态链接库)
gcc -shared -fpic -o libNativeMemoryExample.so NativeMemoryExample.c
- 加载本地库:在Java程序中使用System.loadLibrary()方法加载本地库
public class Main {static {System.loadLibrary("NativeMemoryExample");}public static void main(String[] args) {NativeMemoryExample example = new NativeMemoryExample();example.allocateMemory(1024); // 调用本地方法分配堆外内存// ...example.freeMemory(); // 调用本地方法释放堆外内存}
}
通过以上步骤,Java程序可以使用JNI调用本地方法,在本地代码中进行对JVM堆外内存的分配和释放操作。需要注意的是,在使用JNI时应谨慎管理内存,避免内存泄漏和溢出,确保正确地释放分配的堆外内存
参考资料:
- Java Native Interface
- Direct Buffer
- Native Memory Tracking
相关文章:
JVM 堆外内存详解
Java 进程内存占用除了JVM 运行时数据区,还有直接内存(Direct Memory)区域及 JVM 程序自身也会占用内存 直接内存(Direct Memory)区域:直接内存通过使用Native堆外内存来存储数据,这意味着数据…...
数据库的基本概念以及MySQL基本操作
一、数据库的基本概念 1、数据库的组成 数据:描述事物的符号记录 包括数字,文字、图形、图像、声音、档案记录等 以“记录”形式按统一格式进行存储 表:将不同的记录组织在一起,用来存储具体数据 数据库: 表的集合…...
【Docker】Docker安装Nginx配置静态资源
1.下载镜像 2.创建nginx配置文件 3.创建nginx容器运行 4.配置nginx静态资源 1.下载镜像 Dockerhub官网:Docker docker pull nginx docker pull nginx下载最新版本 默认latest 下载指定版本docker pull nginx:xxx 2.创建nginx配置文件 启动容器之前要创建nginx…...
【码神之路】【Golang】博客网站的搭建【学习笔记整理 持续更新...】
介绍 一个用原生GO开发的博客网站,涉及Golang Web开发、Web服务器搭建和HTTP请求处理、模板与静态资源处理等 技术栈 后端:Go、Go并发机制前端:HTML模版链接直达 Golang搭建博客网站的学习视频 注:这里我只记录我实质✅学习到…...
Win10 电源选项那选择“关闭显示器“为1分钟,1分钟后就锁屏了?怎么才能关闭显示器后不锁屏
环境: Win10专业版 问题描述: Win10 电源选项那选择"关闭显示器"为1分钟,1分钟后就锁屏了?怎么才能关闭显示器后不锁屏 解决方案: 方法一 更改注册表可以实现关闭显示器而不锁屏的效果。请按照以下步骤…...
虚拟机centos设置网络模式(桥接|NAT)
前言 桥接模式是通过物理网卡直接与外部网络建立联系的,而NAT模式则是通过虚拟网卡VMnet1或VMnet8通过宿主机共享IP与外部建立网络关系当需要将虚拟机资源共享给局域网用户使用时,宜采用桥接模式;当需要保护虚拟机资源,确保只能由…...
MySQL 8.2 Command Line Client打开时一闪而过闪退问题
MySQL8.2安装成功后,发现打开MySQL 8.0 Command Line Client时出现一闪而过,打不开的情况。 解决方案: 1、打开MySQL 8.2 Command Line Client文件位置 2、右键选择属性 3、复制它的目标 4、我复制下来的目标路径是这样的,"…...
【NI-RIO入门】CompactRIO介绍及环境安装
CompactRIO是什么? CompactRIO系统提供了高处理性能、传感器专用I/O和紧密集成的软件工具,使其成为工业物联网、监测和控制应用的理想之选。实时处理器提供可靠,可预测的行为,而FPGA在需要高速逻辑和精确定时的较小任务上表现出色…...
生产问题 Recv-Q101
生产上服务端口 Recv-Q101 新请求到服务器的失败,幸好及时发现,通过重启服务之后得到解决,具体原因等待排查 目前觉得的原因是:某些请求暂用时间比较久...
从零开始:Rust环境搭建指南
大家好!我是lincyang。 今天,我们将一起探讨如何从零开始搭建Rust开发环境。 Rust环境搭建概览 Rust是一种系统编程语言,以其安全性、并发性和性能闻名。搭建Rust环境是学习和使用这一语言的第一步。 第一步:安装Rust Rust的…...
Tensorrt 实现 yolov5-cls 遇到的问题
yolov5-6.2增加了分类训练、验证、预测和导出(所有 11 种格式),还提供了 ImageNet 预训练的 YOLOv5m-cls、ResNet(18、34、50、101) 和 EfficientNet (b0-b3) 模型. 官方Git : https://github.com/ultralytics/yolov5 分类模型与…...
智能指针(Newbie Note)
智能指针专题 1.普通指针的问题2.智能指针是什么什么是所有权 3.智能指针三个好处:4.C11提供的智能指针4.1 shared_ptr(共享所有权指针)4.1.1 分配内存4.1.2 成员函数4.1.3 计数情况汇总:4.1.4 示例代码(计数)4.1.5 示例代码(rese…...
2023.11.22 homework
七年级数学 五年级数学 也不知道可以教到几年级,估计很快就教不动了。人生啊。...
存储日志数据并满足安全要求
日志数据是包含有关网络中发生的事件的记录的重要信息,日志数据对于监控网络和了解网络活动、用户操作及其动机至关重要。 由于网络中的每个设备都会生成日志,因此收集的数据量巨大,管理和存储所有这些数据成为一项挑战,日志归档…...
Linux系统管理与服务器安全:构建稳健云数据中心
💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 在当今数字化时代,云数据中心已经成…...
用css实现原生form中radio单选框和input输入框的hover样式以及聚焦focus的样式
一.问题描述:用css实现原生form中radio单选框和input的hover已经focus的样式 在实际的开发中,一般公司ui都会给效果图,比如单选按钮radio样式,input输入框hover的时候样式,以及focus的时候样式,等等&#…...
【中国平安社招校招】【内推】【当天内推】
中国平安社招校招内推 通过内推链接即时内推,反馈速度比正常要快(可私信问进度) 开放大量HC(不限岗位和地区,技术、设计、产品、运营、数据等都可内推) Step1:查看相关职位 浏览平安的招聘官网:复制以下地址至浏览器打开。注意以下链接包含…...
CentOS 8最小安装,VM使用这个内存占用小很多
文章目录 一、安装包下载作者使用的安装包 二、安装过程截图三、最小化安装拥有的外部命令四、查看ip(方便ssh连接)五、yum源有问题参考文档 一、安装包下载 CentOS 网站: https://www.centos.org/CentOS 维基: https://wiki.cen…...
【C++ Primer Plus学习记录】递增运算符(++)和递减运算符(--)
递增运算符()和递减运算符(--):前缀版本位于操作数前面,如x;后缀版本位于操作数后面,如x。两个版本对操作数的影响是一样的,但是影响的时间不同。这就像吃饭前买单和吃饭…...
Oracle 数据库中 查询时如何使用日期(时间)作为查询条件
在 Oracle 数据库中,可以使用日期(时间)作为查询条件来筛选数据。 格式化日期的三种方式 方式一: 关键字 DATE 使用关键字DATE, 仅表示日期类型,并不包含时间信息 方式二:关键字TIMESTAMP 使用关键字TI…...
星露谷物语终极生产力提升指南:5个必备SMAPI模组让你专注游戏乐趣
星露谷物语终极生产力提升指南:5个必备SMAPI模组让你专注游戏乐趣 【免费下载链接】StardewMods Mods for Stardew Valley using SMAPI. 项目地址: https://gitcode.com/gh_mirrors/st/StardewMods 还在为《星露谷物语》中繁琐的农场管理任务而烦恼吗&#x…...
01. 安卓逆向基础、环境搭建与授权
边界说明:本文只面向自研 Demo、开源靶场或已获得书面授权的 App。所有操作目标都是理解 Android 应用结构、验证安全风险、建设防护能力,不用于未授权破解、盗号、绕过付费或攻击第三方服务。1. 本章目标 学完本章后,应能完成四件事…...
深度学习中的对称对比损失及其在面部表情编辑中的应用
1. 项目背景与核心价值面部表情编辑技术近年来在影视特效、虚拟形象生成、人机交互等领域展现出巨大潜力。传统方法往往依赖复杂的3D建模或手工调整参数,而基于深度学习的方法则能够实现更自然的自动化编辑。其中,如何保持身份特征不变的同时精准修改表情…...
基于RAG的智能FAQ系统:从传统检索到语义理解的实战指南
1. 项目概述:从FAQ到智能对话的跃迁如果你负责过任何一个面向用户的网站、应用或服务,那么“FAQ”(常见问题解答)页面一定是你再熟悉不过的模块。它像一个永不疲倦的客服,试图用预设的问答来拦截80%的重复性咨询。但我…...
Cool Pi CM5评估板:RK3588模块化开发平台解析
1. Cool Pi CM5评估板深度解析:基于Rockchip RK3588的模块化开发平台在单板计算机(SBC)领域,Raspberry Pi系列长期占据主导地位,但其计算模块CM4的性能天花板和供货问题促使开发者寻找替代方案。Cool Pi CM5的诞生正是…...
关于OFIRM(本源场直觉共振模型)理论体系的深度解析:数学,检验,预测,证伪【这是对几篇核心基础论文的总结】
关于OFIRM(本源场直觉共振模型)理论体系的深度解析:数学,检验,预测,证伪Authors: Haiting Allen ChenAffiliations: Chen Xiao’er Creative Workshop, Independent Researcher, Guangzhou, China.Corres…...
强化学习与规则引导结合的密集图像描述技术
1. 项目背景与核心价值在计算机视觉领域,密集图像描述(Dense Image Captioning)一直是个极具挑战性的任务。不同于传统图像标注只需生成单一句子描述,密集描述要求对图像中多个显著区域分别生成自然语言描述。这个任务对自动驾驶、…...
git worktree
文章目录1.简介2.格式3.常用选项4.示例4.1 为现有分支创建 worktree4.2 创建新分支并同时创建 worktree4.3 查看所有 worktree4.4 移除不再需要的 worktree4.5 锁定 worktree(防止在 prune 时被清除)4.6 清理已删除的 worktree 引用5.小结参考文献1.简介…...
开源成本监控利器costclaw-telemetry:云原生环境下的成本数据自动化采集实践
1. 项目概述与核心价值最近在折腾一个内部成本监控项目,发现了一个挺有意思的开源工具——queenvest0-ux/costclaw-telemetry。乍一看这个名字,costclaw(成本之爪)和telemetry(遥测),就能猜到它…...
控制权之争:从 Workflow 到 Claude Skills,AI 正在进入「执行契约时代」
读:本文作为《LLM进化史》三部曲终章,让我们看穿AI世界层出不穷的新概念背后的真正本质——所有技术演进,其实都是围绕"谁来决定AI的行为"这一核心问题展开的控制权之争。一、AI圈最大的幻觉:每天都在诞生新技术图&…...
