-XX:MaxDirectMemorySize和-Dio.netty.maxDirectMemory区别

news2024/9/22 21:25:35

-XX:MaxDirectMemorySize是java运行参数,用户控制java程序可以使用的最大直接内存(堆外/本地);

-Dio.netty.maxDirectMemory是netty运行参数,用户控制netty程序可以使用的最大直接内存(堆外/本地);

直接使用JDK代码时:

只有调用了这个java.nio.DirectByteBuffer#DirectByteBuffer(int)构造器方法进行直接内存申请的时候,才会受-XX:MaxDirectMemorySize参数限制。

直接调用Unsafe类,-XX:MaxDirectMemorySize 参数的大小限制对这种是无效的。

原因:

java.nio.DirectByteBuffer#DirectByteBuffer(int)构造器方法受到 -XX:MaxDirectMemorySize 参数的限制,是因为在方法java.nio.DirectByteBuffer方法中在申请内存前需要先
调用Bits.reserveMemory(size, cap)进行预留,如果无法预留,就会抛出OOM;
在Bits.reserveMemory(size, cap)内部不断通过java.nio.Bits#tryReserveMemory尝试
看看有没有足够的堆外内存:cap <= MAX_MEMORY - (totalCap = TOTAL_CAPACITY.get())
这里的 MAX_MEMORY就是-XX:MaxDirectMemorySize 参数值。

// A user-settable upper limit on the maximum amount of allocatable
// direct buffer memory.  This value may be changed during VM
// initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
private static volatile long MAX_MEMORY = VM.maxDirectMemory();
// -XX:MaxDirectMemorySize not given, take default
directMemory = Runtime.getRuntime().maxMemory();
// Runtime.getRuntime().maxMemory();  Returns the maximum amount of memory that the Java virtual machine will attempt to use. If there is no inherent limit then the value Long.MAX_VALUE will be returned.

堆外内存大小:

可以看到,当我们设置了-XX:MaxDirectMemorySize 参数,java.nio.DirectByteBuffer#DirectByteBuffer(int)可以使用的堆外内存最大值就是它;

当我们没有设置-XX:MaxDirectMemorySize 参数,只设置了-Xmx,那么java.nio.DirectByteBuffer#DirectByteBuffer(int)可以使用的堆外内存空间大小就是堆的最大的 可使用的大小。

当我们没有设置-XX:MaxDirectMemorySize 参数,也没有设置了-Xmx ,那么此时java.nio.DirectByteBuffer#DirectByteBuffer(int)可以使用的堆外内存空间大小是Xmx的默认值

而Xmx的默认值一般是物理内存的1/4,但这可能会根据不同的JVM版本和操作系统有所变化。所以最好在生产环境中明确指定这些值。

以我自己的Windows环境为例:

java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize"
   size_t ErgoHeapSizeLimit                        = 0                                         {product} {default}
   size_t HeapSizePerGCThread                      = 43620760                                  {product} {default}
   size_t InitialHeapSize                          = 536870912                                 {product} {ergonomic}
   size_t LargePageHeapSizeThreshold               = 134217728                                 {product} {default}
   size_t MaxHeapSize                              = 8539602944                                {product} {ergonomic}
   size_t MinHeapSize                              = 8388608                                   {product} {ergonomic}
    uintx NonNMethodCodeHeapSize                   = 7602480                                {pd product} {ergonomic}
    uintx NonProfiledCodeHeapSize                  = 122027880                              {pd product} {ergonomic}
    uintx ProfiledCodeHeapSize                     = 122027880                              {pd product} {ergonomic}
   size_t SoftMaxHeapSize                          = 8539602944                             {manageable} {ergonomic}
java version "17.0.8" 2023-07-18 LTS
Java(TM) SE Runtime Environment (build 17.0.8+9-LTS-211)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.8+9-LTS-211, mixed mode, sharing)

Xmx的默认值为size_t MaxHeapSize                              = 8539602944   byte

为8144M,可以通过打印long directMemory = Runtime.getRuntime().maxMemory();来验证

在Linux中查看Java堆大小,Xmx、Xms的默认值和当前运行时的设置值 - 哔哩哔哩

使用Netty代码时:

在Netty中,一般都是通过io.netty.buffer.AbstractByteBufAllocator#directBuffer(int, int)方法申请直接内存的,
该方法内部是调用了io.netty.buffer.AbstractByteBufAllocator#newDirectBuffer, 该方法在不同的实现类中,有不同的实现。
当实现类为:io.netty.buffer.PooledByteBufAllocator:

在io.netty.buffer.PooledByteBufAllocator#newDirectBuffer中:
当PlatformDependent.hasUnsafe()为true的时候:
    1.当要使用Cleaner的时候,最终调用的是JDK中,只在    java.nio.ByteBuffer#allocateDirect这个工具方法中使用,所以受-XX:MaxDirectMemorySize参数限制;
    2.当PlatformDependent.useDirectBufferNoCleaner()(具体逻辑还要看),调用io.netty.util.internal.PlatformDependent0#allocateDirectNoCleaner申请直接内存,此时不受-XX:MaxDirectMemorySize参数限制;受netty的参数限制。
当PlatformDependent.hasUnsafe()为false的时候:
    最终调用的是JDK中,只在    java.nio.ByteBuffer#allocateDirect这个工具方法中使用,所以受-XX:MaxDirectMemorySize参数限制;

当实现类为:io.netty.buffer.UnpooledByteBufAllocator:    
在io.netty.buffer.UnpooledByteBufAllocator#newDirectBuffer中:
当PlatformDependent.hasUnsafe()为true的时候:
    1.当要使用Cleaner的时候,最终调用的是JDK中,只在    java.nio.ByteBuffer#allocateDirect这个工具方法中使用,所以受-XX:MaxDirectMemorySize参数限制;
    2.当noCleaner(具体逻辑还要看),调用io.netty.util.internal.PlatformDependent0#allocateDirectNoCleaner申请直接内存,此时不受-XX:MaxDirectMemorySize参数限制;受netty的参数限制。
当PlatformDependent.hasUnsafe()为false的时候:
    最终调用的是JDK中,只在    java.nio.ByteBuffer#allocateDirect这个工具方法中使用,所以受-XX:MaxDirectMemorySize参数限制;

在Netty 4.0版本中,默认的分配器为UnpooledByteBufAllocator。而在Netty 4.1版本中,默认的分配器为PooledByteBufAllocator;

在netty4.1 以后默认noCleaner策略。

总结:

-XX:MaxDirectMemorySize

默认值是JVM的最大堆内存大小,默认为物理内存的1/4.

使用JDK时:

 调用java.nio.DirectByteBuffer#DirectByteBuffer(int)构造器方法进行直接内存申请的时候,才会受-XX:MaxDirectMemorySize参数限制。

直接调用Unsafe类,-XX:MaxDirectMemorySize 参数的大小限制对这种是无效的。

使用Netty时:

Netty4.1以后,-Dio.netty.maxDirectMemory有用(默认noCleaner策略,-XX:MaxDirectMemorySize不起作用);

Netty4.1以前,-Dio.netty.maxDirectMemory和-Dio.netty.maxDirectMemory都有用

需要进行直接内存限制时,最好两个参数都加上以防万一

参考:

直接内存(堆外内存)-CSDN博客

【Netty学习】七、详解ByteBuf缓冲区_51CTO博客_netty writeandflush并发

Netty11# 非池化内存分配-腾讯云开发者社区-腾讯云 (tencent.com)


 

    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1946785.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQLynx数据库管理工具

背景&#xff1a;业主对网络安全要求比较高&#xff0c;不提供VPN等远程工具&#xff0c;也不能开放3306端口到互联网。那怎么样运维数据库就是个难题&#xff1f;找到了SQLynx这个可以网页访问的数据库管理工具&#xff0c;给大家分享一下。 1.介绍 SQLynx原名SQL Studio&…

如何优化 Selenium 和 BeautifulSoup 的集成以提高数据抓取的效率?

摘要 在互联网时代&#xff0c;数据的价值日益凸显。对于电商网站如京东&#xff0c;其商品信息、用户评价等数据对于市场分析、产品定位等具有重要意义。然而&#xff0c;由于这些网站通常使用 JavaScript 动态生成内容&#xff0c;传统的爬虫技术难以直接获取到完整数据。本…

Vue 实现电子签名并生成签名图片

目录 前言项目结构代码实现 安装依赖创建签名画布组件生成签名图片 总结相关阅读 1. 前言 电子签名在现代Web应用中越来越普遍&#xff0c;例如合同签署、确认表单等。本文将介绍如何使用Vue.js实现一个简单的电子签名功能&#xff0c;并将签名生成图片。 2. 项目结构 项…

基于 LlamaIndex 构建自己的 RAG 知识库

创建虚拟环境用于运行 运行 InternLM 的基础环境&#xff0c;命名为 llamaindex conda create -n llamaindex python3.10 查看存在的环境 conda env list 激活刚刚创建的环境 conda activate llamaindex 安装基本库pytorch,torchvision ,torchaudio,pytorch-cuda 并指定通道&…

动态代理更改Java方法的返回参数(可用于优化feign调用后R对象的统一处理)

动态代理更改Java方法的返回参数&#xff08;可用于优化feign调用后R对象的统一处理&#xff09; 需求原始解决方案优化后方案1.首先创建AfterInterface.java2.创建InvocationHandler处理代理方法3. 调用 实际运行场景拓展 需求 某些场景&#xff0c;调用别人的方法&#xff0…

手机空号过滤批量查询的意义及方法

手机空号过滤批量查询是现代营销和通信管理中常用的技术手段&#xff0c;旨在通过批量处理手机号码&#xff0c;筛选出活跃号码和空号等无效号码&#xff0c;以提高营销效率和减少不必要的通信成本。以下是关于手机空号过滤批量查询的详细解答&#xff1a; 一、手机空号过滤批…

3dsMax 设置近平面削减,靠近模型之后看不到模型,看很小的模型放大看不到

3dsMax 设置近平面削减&#xff0c;靠近模型之后看不到模型&#xff0c;看很小的模型放大看不 问题展示 解决办法_1 把这两个东西最上面的拖拽到最上面&#xff0c;最下面的拖拽到最下面。 解决办法_2 勾选视口裁剪 把这两个东西最上面的拖拽到最上面&#xff0c;最下面的…

华为ensp中ISIS原理与配置(超详细)

isis原理与配置 8-20字节&#xff1b; 地址组成&#xff1a;area id&#xff0c;system id&#xff0c;set三部分组成&#xff1b; system id占6个字节&#xff1b;sel占一个&#xff0c;剩下的为area id区域号&#xff1b; system id 唯一&#xff0c; 一般将router id 配…

opengl 写一个3D立方体——计算机图形学编程 第4章 管理3D图形数据 笔记

计算机图形学编程&#xff08;使用OpenGL和C&#xff09; 第4章 管理3D图形数据 笔记 数据处理 想要绘制一个对象&#xff0c;它的顶点数据需要发送给顶点着色器。通常会把顶点数据在C端放入 一个缓冲区&#xff0c;并把这个缓冲区和着色器中声明的顶点属性相关联。 初始化立…

Python中高效处理大数据的几种方法

随着数据量的爆炸性增长&#xff0c;如何在Python中高效地处理大数据成为了许多开发者和数据科学家的关注焦点。Python以其简洁的语法和丰富的库支持&#xff0c;在数据处理领域占据了重要地位。本文将介绍几种在Python中高效处理大数据的常用方法。 目录 1. 使用Pandas进行数…

基于STM32的逻辑分析仪

文章目录 一、逻辑分析仪体验1、使用示例1.1 逻辑分析仪1.2 开源软件PulseView 2、核心技术2.1 技术方案2.2 信号采集与存储2.3 数据上传 3、使用逻辑分析仪4、 SourceInsight 使用技巧4.1新建工程4.2 设置工程名及工程数据目录4.3 指定源码目录4.4 添加源码4.5 同步文件4.6 操…

为RTEMS Raspberrypi4 BSP添加SPI支持

为RTEMS Raspberrypi4 BSP添加SPI支持 主要参考了dev/bsps/shared/dev/spi/cadence-spi.c RTEMS 使用了基于linux的SPI框架&#xff0c;SPI总线驱动已经在内核中实现。在这个项目中我需要实习的是 RPI4的SPI主机控制器驱动 SPI在RTEMS中的实现如图&#xff1a; 首先需要将S…

25.x86游戏实战-理解发包流程

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

江科大/江协科技 STM32学习笔记P9-11

文章目录 OLED1、OLED硬件main.c EXTI外部中断1、中断系统2、中断执行流程图3、STM32中断4、中断地址的作用5、EXTI6、EXTI基本结构7、AFIO复用IO口8、EXTI框图或门和与门 9、旋转编码器介绍10、硬件电路 OLED 1、OLED硬件 SCL和SDA是I2C的通信引脚&#xff0c;需要接在单片机…

java包装类型缓存简单探究-Integer为例

文章目录 包装类型缓存自动装箱与valueOf感悟结语 包装类型缓存 包装类型缓存是什么 本文以常用的Integer包装类为例做一个探索&#xff0c;感兴趣可以用类似方法查看其他包装类。 我们都知道它会缓存 -128到127之间的整数Integer对象。 结论大伙都知道。那么我们今天就来探究…

【Android】安卓四大组件之广播知识总结

文章目录 动态注册使用BroadcastReceiver监听Intent广播注册Broadcast Receiver 静态注册自定义广播标准广播发送广播定义广播接收器注册广播接收器 有序广播修改发送方法定义第二个广播接收器注册广播接收器广播截断 使用本地广播实践-强制下线使用ActivityCollector管理所有活…

ubuntu那些ppa源在哪

Ubuntu中的 PPA 终极指南 - UBUNTU粉丝之家 什么是PPA PPA 代表个人包存档。 PPA 允许应用程序开发人员和 Linux 用户创建自己的存储库来分发软件。 使用 PPA&#xff0c;您可以轻松获取较新的软件版本或官方 Ubuntu 存储库无法提供的软件。 为什么使用PPA&#xff1f; 正如…

【JavaEE】Spring Boot 自动装配原理(源码分析)

一. 前言 我们在写Spring Boot的程序代码的时候, 可以注入很多我们没有定义过的Bean.例如: Autowired private ApplicationContext applicationContext; Autowired public DataSourceTransactionManager transactionManager; Autowired public AutowireCapableBeanFactory …

软件开发者消除edge浏览器下载时“此应用不安全”的拦截方法

当Microsoft Edge浏览器显示“此应用不安全”或者“已阻止此不安全的下载”这类警告时&#xff0c;通常是因为Windows Defender SmartScreen或者其他安全功能认为下载的文件可能存在安全风险。对于软件开发者来说&#xff0c;大概率是由于软件没有进行数字签名&#xff0c;导致…

Visual Studio 2022新建 cmake 工程测试 tensorRT 自带样例 sampleOnnxMNIST

1. 新建 cmake 工程 vs2022_cmake_sampleOnnxMNIST_test( 如何新建 cmake 工程&#xff0c;请参考博客&#xff1a;Visual Studio 2022新建 cmake 工程测试 opencv helloworld ) 2. 删除默认生成的 vs2022_cmake_sampleOnnxMNIST_test.h 头文件 3. 修改默认生成的 vs2022_cma…