Linux - 记一次某Java程序启动报错(申请内存失败)

文章目录

  • 问题
  • 可能原因分析
    • 可能原因分析
    • 尝试各种解决方案
    • 尝试解决过程
  • 解决办法: 调整 overcommit_meory参数
  • overcommit_memory详解
    • 什么是 `overcommit_memory`?
    • `overcommit_memory` 的选项及其含义
    • 配置 `overcommit_memory`
      • 查看当前设置
      • 设置 `overcommit_memory`
      • 配置 `overcommit_ratio`
    • 参数设置对系统的影响
      • 启发式内存分配(0)
      • 总是允许内存分配(1)
      • 禁止过度分配(2)
    • 实例与使用建议
      • 数据库服务器
      • 高性能计算应用
  • RedHat官网调优指南 (临时或永久改变系统的内存管理行为)
    • 临时调整内存参数
    • 永久调整内存参数
    • 参考命令

在这里插入图片描述


问题

启动的时候直接抛出如下异常

Native memory allocation (mmap) failed to map 2879048192 bytes for committing reserved memory

在 Linux 上部署项目时遇到 Native memory allocation (mmap) failed to map 2879048192 bytes for committing reserved memory 错误,这通常表明系统在尝试分配内存时遇到了问题。虽然 free 命令显示有足够的可用内存,并且 ulimit -a 显示内存没有被限制,但仍可能有其他原因导致该问题。


可能原因分析

可能原因分析

  1. 内存碎片化

    • 尽管 free 显示有足够的可用内存,但这些内存可能不是连续的。mmap 需要分配连续的内存块,如果内存碎片化严重,可能无法找到足够大的连续内存块。
  2. 地址空间不足

    • 32 位系统的虚拟地址空间有限,即使物理内存充足,虚拟地址空间也可能不足。
    • 64 位系统通常不太可能出现这个问题,但在极端情况下(例如,系统运行多个内存密集型应用程序)也可能发生。
  3. 内核参数限制

    • 某些内核参数(如 vm.max_map_countvm.overcommit_memory)可能限制了内存分配。
  4. 容器或虚拟机限制

    • 如果在 Docker 容器或虚拟机中运行应用程序,容器或虚拟机本身可能有内存限制。

尝试各种解决方案

  1. 检查内存碎片化

    • 使用 cat /proc/meminfo 查看内存详细信息。
    • 重点关注 MemFreeMemAvailableHugePages_TotalHugePages_Free
    • 使用 sudo sysctl -a | grep vm.min_free_kbytes 确认内核保留的最小空闲内存。
  2. 调整内核参数

    • vm.max_map_count:最大 mmap 区域数。
      sudo sysctl -w vm.max_map_count=262144
      
    • vm.overcommit_memory:内存过度提交策略。 【我们通过调整参数,临时修复了该问题
      sudo sysctl -w vm.overcommit_memory=1
      
  3. 检查虚拟地址空间

    • 确保系统运行在 64 位模式下。
    • 检查应用程序是否有特定的内存限制。
  4. 检查容器/虚拟机限制

    • 对于 Docker 容器:
      docker inspect <container_id> | grep Memory
      
    • 对于虚拟机,检查虚拟机管理工具的内存设置。

尝试解决过程

  1. 检查内存详细信息:

    cat /proc/meminfo
    
  2. 检查内核参数:

    sudo sysctl -a | grep vm
    
  3. 调整内核参数:

    sudo sysctl -w vm.max_map_count=262144
    sudo sysctl -w vm.overcommit_memory=1
    
  4. 检查 Docker 容器内存设置:

    docker inspect <container_id> | grep Memory
    
    

解决办法: 调整 overcommit_meory参数

调整 overcommit_meory参数。
在这里插入图片描述


overcommit_memory详解

在 Linux 操作系统中,内存分配是一个关键的任务。内存的高效使用和管理直接影响系统的性能和稳定性。overcommit_memory 是一个重要的内核参数,用于控制内存分配策略。

什么是 overcommit_memory

overcommit_memory 是 Linux 内核中的一个参数,通过 /proc/sys/vm/overcommit_memory 文件进行配置。它决定了内核如何处理内存分配请求,尤其是在可用物理内存不足的情况下。

overcommit_memory 的选项及其含义

overcommit_memory 参数有三个可能的值,每个值对应一种特定的内存分配策略:

  1. 0 - 启发式内存分配(默认值)

    • 内核根据一定的启发式算法决定是否允许内存分配请求。内核会考虑当前的内存使用情况和预期的内存需求,通常会允许合理范围内的内存过度分配。
    • 优点:灵活性较高,适合大多数应用场景。
    • 缺点:可能在内存非常紧张时导致 OOM(Out Of Memory)错误。
  2. 1 - 总是允许内存分配

    • 内核允许所有内存分配请求,无论当前的内存使用情况如何。这意味着即使系统内存已经耗尽,内核也会继续分配内存。
    • 优点:极大的灵活性,确保所有内存分配请求都能成功。
    • 缺点:可能导致严重的内存不足问题,甚至导致系统崩溃。
  3. 2 - 禁止过度分配

    • 内核严格限制内存分配,只有在有足够的物理内存和交换空间时才允许内存分配请求。这个策略会结合 overcommit_ratio 参数来确定可用的内存总量。
    • 优点:提高系统稳定性,防止 OOM 错误。
    • 缺点:降低内存分配灵活性,可能拒绝一些合理的内存分配请求。

配置 overcommit_memory

可以通过以下命令查看和设置 overcommit_memory 参数:

查看当前设置

cat /proc/sys/vm/overcommit_memory

设置 overcommit_memory

例如,将 overcommit_memory 设置为 1:

echo 1 > /proc/sys/vm/overcommit_memory

配置 overcommit_ratio

如果 overcommit_memory 设置为 2,还需要配置 overcommit_ratio 参数来决定可用内存总量。overcommit_ratio 是一个百分比值,表示可分配的物理内存和交换空间的比例。

echo 50 > /proc/sys/vm/overcommit_ratio

这个配置表示内核允许分配的内存总量为物理内存加上 50% 的交换空间。

参数设置对系统的影响

启发式内存分配(0)

这种设置平衡了灵活性和稳定性,适合大多数应用场景。系统会尝试合理地分配内存,防止过度分配,但在极端情况下可能仍会遇到 OOM 错误。

总是允许内存分配(1)

这种设置提供了最大的灵活性,但也伴随着最高的风险。适用于需要极大内存灵活性的场景,如高性能计算或科学计算,但需注意可能的内存不足问题。

禁止过度分配(2)

这种设置提供了最大的稳定性,适用于需要严格内存控制的场景,如数据库服务器或关键业务应用。通过合理设置 overcommit_ratio,可以确保系统不会因内存不足而崩溃。

实例与使用建议

数据库服务器

对于数据库服务器,建议使用禁止过度分配的策略(设置 overcommit_memory 为 2),并合理配置 overcommit_ratio 以确保稳定性。例如,对于一个拥有 16GB 内存和 8GB 交换空间的系统,可以将 overcommit_ratio 设置为 50:

echo 2 > /proc/sys/vm/overcommit_memory
echo 50 > /proc/sys/vm/overcommit_ratio

高性能计算应用

对于高性能计算应用,可以考虑启用总是允许内存分配的策略(设置 overcommit_memory 为 1),以确保所有内存分配请求都能成功:

echo 1 > /proc/sys/vm/overcommit_memory

RedHat官网调优指南 (临时或永久改变系统的内存管理行为)

https://docs.redhat.com/zh_hans/documentation/red_hat_enterprise_linux/6/html/performance_tuning_guide/s-memory-captun

在 Linux 上,调整内存相关参数可以临时或永久改变系统的内存管理行为。

临时调整内存参数

临时调整内存参数可以通过向 /proc/sys 文件系统中的相应文件写入值来实现。这种方法在系统重启后会失效,需要重新设置。

  1. 调整 overcommit_memory 参数

    echo 1 > /proc/sys/vm/overcommit_memory
    
  2. 调整 overcommit_ratio 参数

    echo 50 > /proc/sys/vm/overcommit_ratio
    
  3. 调整 max_map_count 参数

    echo 262144 > /proc/sys/vm/max_map_count
    
  4. 调整 nr_hugepages 参数

    echo 128 > /proc/sys/vm/nr_hugepages
    
  5. 调整其他相关参数

    echo 65536 > /proc/sys/kernel/msgmax
    echo 65536 > /proc/sys/kernel/msgmnb
    echo 1985 > /proc/sys/kernel/msgmni
    echo 4294967296 > /proc/sys/kernel/shmall
    echo 68719476736 > /proc/sys/kernel/shmmax
    echo 4096 > /proc/sys/kernel/shmmni
    echo 32768 > /proc/sys/kernel/threads-max
    echo 65536 > /proc/sys/fs/aio-max-nr
    echo 1048576 > /proc/sys/fs/file-max
    

永久调整内存参数

为了使内存参数的调整在系统重启后依然有效,可以将这些设置写入 /etc/sysctl.conf 文件,或在 /etc/sysctl.d/ 目录下创建一个新的配置文件。

  1. 编辑 /etc/sysctl.conf 文件

    sudo nano /etc/sysctl.conf
    

    添加以下内容:

    vm.overcommit_memory = 1
    vm.overcommit_ratio = 50
    vm.max_map_count = 262144
    vm.nr_hugepages = 128
    kernel.msgmax = 65536
    kernel.msgmnb = 65536
    kernel.msgmni = 1985
    kernel.shmall = 4294967296
    kernel.shmmax = 68719476736
    kernel.shmmni = 4096
    kernel.threads-max = 32768
    fs.aio-max-nr = 65536
    fs.file-max = 1048576
    
  2. 创建新的配置文件(例如 /etc/sysctl.d/99-custom.conf

    sudo nano /etc/sysctl.d/99-custom.conf
    

    添加相同的内容:

    vm.overcommit_memory = 1
    vm.overcommit_ratio = 50
    vm.max_map_count = 262144
    vm.nr_hugepages = 128
    kernel.msgmax = 65536
    kernel.msgmnb = 65536
    kernel.msgmni = 1985
    kernel.shmall = 4294967296
    kernel.shmmax = 68719476736
    kernel.shmmni = 4096
    kernel.threads-max = 32768
    fs.aio-max-nr = 65536
    fs.file-max = 1048576
    
  3. 应用配置

    sudo sysctl -p
    

参考命令

  • 临时调整参数

    echo 1 > /proc/sys/vm/overcommit_memory
    echo 262144 > /proc/sys/vm/max_map_count
    
  • 永久调整参数

    sudo nano /etc/sysctl.d/99-custom.conf
    sudo sysctl -p
    

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

# linux 系统中,使用 “ ll “ 命令报错 “ bash ll command not found “ 解决方法:

linux 系统中&#xff0c;使用 " ll " 命令报错 " bash ll command not found " 解决方法&#xff1a; 一、错误描述&#xff1a; 报错原因&#xff1a; 1、这个错误表明你尝试在 bash shell 中执行 ll 命令&#xff0c;但是系统找不到这个命令。ll 通常…

Nvidia显卡GeForce Experience录屏操作流程

安装软件 首先我们从英伟达官网下载GeForce Experience程序&#xff0c;安装在电脑中GeForce Experience&#xff08;简称 GFE&#xff09;自动更新驱动并优化游戏设置 | NVIDIA 登录软件 安装完成后登录 开启录屏功能 登录后点击右上角的设置&#xff08;小齿轮图标&#x…

接口自动化测试关联token的方法?

引言&#xff1a; 在接口自动化测试中&#xff0c;有时候我们需要关联token来进行身份验证或权限管理。本文将从零开始&#xff0c;介绍如何详细且规范地实现接口自动化测试中token的关联。 步骤一&#xff1a;准备工作 在开始之前&#xff0c;我们需要确保以下准备工作已完成…

UE5(c++)demo开发日志(1):Actor类添加

工具---新建c类---选用Actor&#xff0c;创造出头文件(.h&#xff0c;用于声明变量、函数、重写父类函数等)和源文件(.cpp&#xff0c;涉及到具体功能实现)&#xff0c;客户端界面成功显示出来新建类&#xff1a; Actor头文件默认方法简介&#xff1a; UCLASS(): ue提供的宏&a…

前端工程化08-新的包管理工具pnpm

1、历史原因解读 pnpm这个东西发布的时间是比较早的&#xff0c;但是在最近一两年的时候才开始流行&#xff0c;甚至是可以说非常的盛行&#xff0c;那么这个包到底是个什么东西的&#xff0c;那么我们先说下&#xff0c;原来的包管理工具到底有那些问题&#xff1f;比如说我们…

第三阶段Spark

Spark和PySpark的介绍 PySpark的相关设置 安装PySpark库 pip install pyspark pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyspark 构建PySpark执行环境入口对象 # 导包 from pyspark import SparkConf, SparkContext# 创建SparkConf类对象 conf SparkConf()…

C++进修——C++核心编程

内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区&#xff1a;存放函数体的二进制编码&#xff0c;由操作系统进行管理全局区&#xff1a;存放全局变量和静态变量以及常量栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数值&#xff…

谈一下MySQL的两阶段提交机制

文章目录 为什么需要两阶段提交&#xff1f;两阶段提交流程&#xff1f;两阶段提交缺点&#xff1f; 为什么需要两阶段提交&#xff1f; 为了保证事务的持久性和一致性&#xff0c;MySQL需要确保redo log和binlog的同步持久化。MySQL通过“两阶段提交”的机制来实现在事务提交…

Python 面试【初级】

欢迎莅临我的博客 &#x1f49d;&#x1f49d;&#x1f49d;&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

安卓开发自定义时间日期显示组件

安卓开发自定义时间日期显示组件 问题背景 实现时间和日期显示&#xff0c;左对齐和对齐两种效果&#xff0c;如下图所示&#xff1a; 问题分析 自定义view实现一般思路&#xff1a; &#xff08;1&#xff09;自定义一个View &#xff08;2&#xff09;编写values/attrs.…

day57---面试专题(框架篇)

框架篇 1. Spring refresh 流程 要求 掌握 refresh 的 12 个步骤Spring refresh 概述 refresh 是 AbstractApplicationContext 中的一个方法,负责初始化 ApplicationContext 容器,容器必须调用 refresh 才能正常工作。它的内部主要会调用 12 个方法,我们把它们称为 refre…

【JavaScript】JavaScript简介

希望文章能给到你启发和灵感&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏 支持一下博主吧&#xff5e; 阅读指南 JavaScript入门&#xff08;1&#xff09;————JavaScript简介开篇说明一、什么是JavaScript二、JavaScript的使用2.1 开发工具的选择…

上市公司环境研究汇总数据集(2008-2022年)

数据简介&#xff1a;上市公司环境研究是指对上市公司在环境保护和可持续发展方面的表现和做法进行评估和研究。这些评估可以包括上市公司的环境风险、环境管理制度和政策、环境负债和环境绩效等方面。 上市公司环境研究可以帮助上市公司更好地了解自身的环境状况和风险&#…

FastAPI教程II

本文参考FastAPI教程https://fastapi.tiangolo.com/zh/tutorial Cookie参数 定义Cookie参数与定义Query和Path参数一样。 具体步骤如下&#xff1a; 导入Cookie&#xff1a;from fastapi import Cookie声明Cookie参数&#xff0c;声明Cookie参数的方式与声明Query和Path参数…

[单机版架设]新天堂2-死亡骑士338|带AI机器人

前言 今天给大家带来一款单机游戏的架设&#xff1a;新天堂2-死亡骑士338单机服务端—带AI机器人 如今市面上的资源参差不齐&#xff0c;大部分的都不能运行&#xff0c;本人亲自测试&#xff0c;运行视频如下&#xff1a; 新天堂2 搭建教程 此游戏架设不需要虚拟机&#xf…

android轮播图入门1——简单无限自动轮播图

目标 目标是实现一个简单的轮播图&#xff0c;特征如下&#xff1a; 只展示本地图片可以无限轮播&#xff0c;在第一帧时也可以向前轮播可以自动轮播 code 先上代码&#xff0c;需要事先准备几张本地图片当素材 MainActivity: package com.example.loopapplication;import…

1-Pandas是什么

Pandas是什么 Pandas 是一个开源的第三方 Python 库&#xff0c;从 Numpy 和 Matplotlib 的基础上构建而来&#xff0c;享有数据分析“三剑客之一”的盛名&#xff08;NumPy、Matplotlib、Pandas&#xff09;。Pandas 已经成为 Python 数据分析的必备高级工具&#xff0c;它的…

nginx 1024 worker_connections are not enough while connecting to upstream

现象 请求api响应慢&#xff0c;甚至出现504 gateway timeout&#xff0c;重启后端服务不能恢复&#xff0c;但重启nginx可以恢复。 解决方案 worker_connections使用了默认值 1024&#xff0c;当流量增长时&#xff0c;导致连接不够 在nginx.conf中修改连接数就可以了&…

pg_rman:备份和恢复管理工具#postgresql培训

pg_rman 是 PostgreSQL 的在线备份和恢复工具。 pg_rman 项目的目标是提供一种与 pg_dump 一样简单的在线备份和 PITR 方法。此外&#xff0c;它还为每个数据库集群维护一个备份目录。用户只需一个命令即可维护包括存档日志在内的旧备份。 #PG培训#PG考试#postgresql考试#pos…

基于Spring Boot与Vue的智能房产匹配平台+文档

博主介绍&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐&#xff1a;最热的500个选题…