Linux 下 Java 的虚拟内存使用情况,使用了太多内存

2024-01-13

我在 Linux 下运行 Java 应用程序时遇到问题。

当我使用默认最大堆大小 (64 MB) 启动应用程序时,我看到使用 tops 应用程序为该应用程序分配了 240 MB 虚拟内存。这会给计算机上的一些其他软件带来一些问题,而计算机的资源相对有限。

据我了解,保留的虚拟内存无论如何都不会被使用,因为一旦我们达到堆限制OutOfMemoryError被抛出。我在 Windows 下运行相同的应用程序,发现虚拟内存大小和堆大小相似。

无论如何,我可以在 Linux 下配置 Java 进程使用的虚拟内存吗?

Edit 1: 问题不在于堆。问题是,例如,如果我设置 128 MB 的堆,Linux 仍然会分配 210 MB 的虚拟内存,而这是永远不需要的。**

Edit 2: Using ulimit -v允许限制虚拟内存量。如果设置的大小低于 204 MB,则应用程序将无法运行,即使它不需要 204 MB,只需要 64 MB。所以我想了解为什么Java需要这么多的虚拟内存。这可以改变吗?

Edit 3:系统中还运行着其他几个嵌入式应用程序。而且系统确实有虚拟内存限制(来自评论,重要细节)。


这是对 Java 的长期抱怨,但它基本上没有意义,并且通常基于查看错误的信息。通常的措辞类似于“Java 上的 Hello World 需要 10 兆字节!为什么需要这个?”好吧,这里有一种方法可以让 64 位 JVM 上的 Hello World 声称占用超过 4 GB 的空间……至少通过一种测量形式是这样。



java -Xms1024m -Xmx4096m com.example.Hello
  

测量内存的不同方法

在 Linux 上,top http://linux.die.net/man/1/top命令为您提供了几个不同的内存数字。以下是关于 Hello World 示例的内容:



  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 2120 kgregory  20   0 4373m  15m 7152 S    0  0.2   0:00.10 java
  
  • VIRT 是虚拟内存空间:虚拟内存映射中所有内容的总和(见下文)。它基本上没有意义,除非它没有意义(见下文)。
  • RES 是驻留集大小:当前驻留在 RAM 中的页数。在几乎所有情况下,这是在说“太大”时应该使用的唯一数字。但这仍然不是一个很好的数字,尤其是在谈论 Java 时。
  • SHR 是与其他进程共享的常驻内存量。对于 Java 进程,这通常仅限于共享库和内存映射 JAR 文件。在此示例中,我只运行了一个 Java 进程,因此我怀疑 7k 是操作系统使用的库的结果。
  • 默认情况下,SWAP 未打开,因此此处未显示。它表示当前驻留在磁盘上的虚拟内存量,它是否实际上在交换空间中。操作系统非常擅长将活动页面保留在 RAM 中,而交换的唯一解决方法是 (1) 购买更多内存,或 (2) 减少进程数量,因此最好忽略这个数字。

Windows 任务管理器的情况稍微复杂一些。在Windows XP下,有“内存使用情况”和“虚拟内存大小”栏,但官方文档 http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/taskman_whats_there_w.mspx?mfr=true对他们的意思保持沉默。 Windows Vista 和 Windows 7 添加了更多列,它们实际上是有记录的 http://windows.microsoft.com/en-US/windows7/see-details-about-your-computers-performance-using-task-manager。其中,“工作集”测量是最有用的;它大致相当于 Linux 上 RES 和 SHR 的总和。

了解虚拟内存映射

进程消耗的虚拟内存是进程内存映射中所有内容的总和。这包括数据(例如,Java 堆),还包括程序使用的所有共享库和内存映射文件。在 Linux 上,您可以使用pmap http://linux.die.net/man/1/pmap命令来查看映射到进程空间中的所有内容(从这里开始我将仅参考 Linux,因为这是我使用的;我确信 Windows 上有等效的工具)。这是“Hello World”程序的内存映射的摘录;整个内存映射超过 100 行长,一千行列表并不罕见。



0000000040000000     36K r-x--  /usr/local/java/jdk-1.6-x64/bin/java
0000000040108000      8K rwx--  /usr/local/java/jdk-1.6-x64/bin/java
0000000040eba000    676K rwx--    [ anon ]
00000006fae00000  21248K rwx--    [ anon ]
00000006fc2c0000  62720K rwx--    [ anon ]
0000000700000000 699072K rwx--    [ anon ]
000000072aab0000 2097152K rwx--    [ anon ]
00000007aaab0000 349504K rwx--    [ anon ]
00000007c0000000 1048576K rwx--    [ anon ]
...
00007fa1ed00d000   1652K r-xs-  /usr/local/java/jdk-1.6-x64/jre/lib/rt.jar
...
00007fa1ed1d3000   1024K rwx--    [ anon ]
00007fa1ed2d3000      4K -----    [ anon ]
00007fa1ed2d4000   1024K rwx--    [ anon ]
00007fa1ed3d4000      4K -----    [ anon ]
...
00007fa1f20d3000    164K r-x--  /usr/local/java/jdk-1.6-x64/jre/lib/amd64/libjava.so
00007fa1f20fc000   1020K -----  /usr/local/java/jdk-1.6-x64/jre/lib/amd64/libjava.so
00007fa1f21fb000     28K rwx--  /usr/local/java/jdk-1.6-x64/jre/lib/amd64/libjava.so
...
00007fa1f34aa000   1576K r-x--  /lib/x86_64-linux-gnu/libc-2.13.so
00007fa1f3634000   2044K -----  /lib/x86_64-linux-gnu/libc-2.13.so
00007fa1f3833000     16K r-x--  /lib/x86_64-linux-gnu/libc-2.13.so
00007fa1f3837000      4K rwx--  /lib/x86_64-linux-gnu/libc-2.13.so
...
  

格式的快速解释:每一行都以段的虚拟内存地址开始。接下来是段大小、权限和段的来源。最后一项是文件或“anon”,它表示通过分配的内存块mmap http://linux.die.net/man/2/mmap.

从顶部开始,我们有

  • JVM 加载程序(即,当您键入java)。这是非常小的;它所做的只是加载到存储真实 JVM 代码的共享库中。
  • 一堆保存 Java 堆和内部数据的匿名块。这是Sun JVM,因此堆被分成多代,每一代都是自己的内存块。请注意,JVM 根据以下方式分配虚拟内存空间:-Xmx价值;这允许它有一个连续的堆。这-Xmsvalue 在内部使用来表示程序启动时有多少堆“正在使用”,并在接近该限制时触发垃圾回收。
  • 内存映射 JAR 文件,在本例中是保存“JDK 类”的文件。当您对 JAR 进行内存映射时,您可以非常有效地访问其中的文件(而不是每次都从头读取它)。 Sun JVM 将内存映射类路径上的所有 JAR;如果您的应用程序代码需要访问 JAR,您还可以对其进行内存映射。
  • 两个线程的每线程数据。 1M块就是线程栈。我对 4k 块没有很好的解释,但 @ericsoe 将其标识为“保护块”:它没有读/写权限,因此如果访问会导致段错误,JVM 会捕获并翻译它它到一个StackOverFlowError。对于真正的应用程序,您将看到数十个(如果不是数百个)这些条目在内存映射中重复出现。
  • 保存实际 JVM 代码的共享库之一。其中有几个。
  • C 标准库的共享库。这只是 JVM 加载的许多东西之一,这些东西严格来说不是 Java 的一部分。

共享库特别有趣:每个共享库至少有两个段:一个包含库代码的只读段,以及一个包含该库的全局每进程数据的读写段(我不知道这是什么)没有权限的段是;我只在 x64 Linux 上看到过它)。库的只读部分可以在使用该库的所有进程之间共享;例如,libc拥有1.5M可共享的虚拟内存空间。

虚拟内存大小何时很重要?

虚拟内存映射包含很多东西。其中一些是只读的,一些是共享的,还有一些已分配但从未被触及(例如,本例中几乎所有 4Gb 堆)。但操作系统足够聪明,只能加载它需要的内容,因此虚拟内存大小在很大程度上是无关紧要的。

虚拟内存大小很重要的地方是,如果您运行在 32 位操作系统上,则只能分配 2Gb(或在某些情况下,3Gb)的进程地址空间。在这种情况下,您正在处理稀缺资源,并且可能必须做出权衡,例如减小堆大小以便内存映射大文件或创建大量线程。

但是,考虑到 64 位机器无处不在,我认为用不了多久虚拟内存大小就会成为一个完全无关的统计数据。

驻留集大小何时很重要?

驻留集大小是实际位于 RAM 中的虚拟内存空间部分。如果您的 RSS 占据了总物理内存的很大一部分,那么可能是时候开始担心了。如果您的 RSS 增长到占用了您所有的物理内存,并且您的系统开始交换,那么您就不必开始担心了。

但 RSS 也具有误导性,尤其是在负载较轻的机器上。操作系统不会花费大量精力来回收进程使用的页面。这样做几乎没有什么好处,而且如果该进程将来接触该页面,则可能会出现昂贵的页面错误。因此,RSS 统计信息可能包含大量未活跃使用的页面。

底线

除非您要进行交换,否则不要过分关心各种内存统计信息告诉您什么。需要注意的是,不断增长的 RSS 可能表明存在某种内存泄漏。

对于 Java 程序,关注堆中发生的情况要重要得多。消耗的空间总量很重要,您可以采取一些步骤来减少空间消耗。更重要的是您在垃圾收集上花费的时间,以及堆的哪些部分被收集。

访问磁盘(即数据库)很昂贵,而内存很便宜。如果你可以用其中之一交换另一个,那就这样做吧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux 下 Java 的虚拟内存使用情况,使用了太多内存 的相关文章

  • 确定范围是否重叠

    给定两个具有整数开始时间和结束时间的事件 E1 s1 e1 E2 s2 e2 实现快速布尔检查以查看事件是否重叠 我有解决方案 但我很想看看其他人想出了什么 编辑 好的 这是我的解决方案 e1 gt s2 s1 gt s2 e2 lt s1
  • 在 ElasticSearch API 应用程序中找不到 NodeBuilder

    我正在尝试实现 Elasticsearch API 我的系统接受 nodeBuilder 时出现错误 这是代码 import org elasticsearch action index IndexResponse import org e
  • MySQL 中电话号码的最佳数据类型是什么?它的 Java 类型映射应该是什么?

    我正在将 MySQL 与 Spring JDBC 模板一起用于我的 Web 应用程序 我需要存储仅包含数字的电话号码 10 我对使用数据类型的数据类型有点困惑 MySQL 中最适合它的数据类型是什么 为此 Bean POJO 类中的 Jav
  • 无法在 Spring boot 中使用 findOne() 方法

    我的项目是关于用户管理器网络的 我是 Spring 和 Java 的新手 这是我的代码 在 UserController 中 RequestMapping value users name method RequestMethod GET
  • Clojure Web 应用程序 - 我从哪里开始?

    最近我一直在研究 Clojure 我喜欢这门语言 我想看看我是否可以在其中制作一个小型网络应用程序 只是为了挑战自己 但是 我完全没有设置任何与 Java 相关的 Web 应用程序的经验 事实上 我对 Java 并没有太多的经验 我从哪说起
  • 如何使用 apache commons cli 指定多个选项?

    我想要这样的东西 java programName jobs1 C 10 W 20 java programName job2 java programName job3 含内容 Option o1 new Option job2 some
  • 如何避免 OrderBy - 内存使用问题

    假设我们有一个很大的点列表List
  • 在单个命令中使用前缀重命名文件夹中的所有文件

    重命名带有前缀的文件夹中的所有文件 Unix 假设一个文件夹有两个文件 a txt b pdf 那么它们都应该从一个命令重命名为 Unix a txt Unix b pdf 如果您的文件名包含没有空格并且你没有任何子目录 你可以使用一个简单
  • 将 JAR 文件打包为 WAR 文件

    我有一系列依赖的Java项目 我想将它们打包成一个 JAR 文件 以便在我的 WAR 文件中使用 这些项目依赖于大量的外部库和项目 如log4j apache commons等 我选择 Eclipse 中的所有项目并导出为 JAR 文件 然
  • 如何在 Spring Boot 中访问 application.properties 文件中定义的值

    我想访问中提供的值application properties e g logging level org springframework web DEBUG logging level org hibernate ERROR loggin
  • 如何在 groovy 中将输出重定向到 stderr?

    我正在寻找一种将 groovy 脚本中的输出重定向到 stderr 的方法 catch Exception e println Want this to go to stderr 就在我的脑海中 你不能做一些自我接线吗 def printE
  • Mono 和 WebRequest 速度 - 测试

    在 mono 4 6 2 linux 中 我注意到 wget 下载文件的速度与webclient DownloadString 所以我做了一个小测试来调查 为什么 wget 明显比 C 快 根据我自己的实验 使用 wget 下载 手动读取文
  • 从 Linux 命令行发送 SNMP 陷阱消息

    Folks 我需要从 Linux 命令行使用此命令 snmptrap 将自定义消息发送到陷阱侦听器 我需要根据用户设置在 v1 和 v2c 中发送相同的消息 这是我发现的 For v1 snmptrap v 1 c Tas hostname
  • 运行 JAR 时“JCE 无法验证提供者 BC”

    在我的 scala 项目中我使用 org bouncycastle bcprov jdk14 1 51 用于密码学 如果它在 Scala IDE 中测试我的项目 它工作得很好 但是一旦我制作了一个 JAR 并尝试通过以下方式运行它java
  • 如何提高QNX6下Eclipse IDE的性能

    我们在 VMWare 环境中通过 QNX6 运行 Eclipse 速度非常慢 Eclipse 是这样启动的 usr qnx630 host qnx6 x86 usr qde eclipse eclipse data root workspa
  • 演员邮箱溢出。斯卡拉

    我目前正在与 scala 的两位演员合作 一 producer 产生一些数据并将其发送到parcer 生产者发送一个HashMap String HashMap Object List Int 通过消息 以及this标记发件人 parcer
  • 跟踪 pthread 调度

    我想做的是创建某种图表 详细说明 Linux 中 两个 线程的执行情况 我不需要查看线程的作用 只需查看它们何时被安排以及持续多长时间 基本上是一条时间线 在过去的几个小时里 我一直在互联网上搜索跟踪 pthread 调度的方法 不幸的是
  • 在同一项目上使用 Eclipse 和 NetBeans

    Eclipse 是一个非常棒的编辑器 我更喜欢使用它 但是缺少 Eclipse 的 GUI 设计工具 另一方面 NetBeans 非常适合 GUI 设计 在同一项目中使用 NetBeans 进行 GUI 设计和 Eclipse 进行其他所有
  • 在 Eclipse Testrunner 中使用名称的 ParameterizedTest

    当您使用 Eclipse TestRunner 运行 JUnit 4 ParameterizedTest 时 图形表示相当愚蠢 对于每个测试 您都有一个名为 0 1 ETC 是否可以进行测试 0 1 等显式名称 实施一个toString测试
  • Alsa 带有来自调制解调器的 PCM 接口

    我有一个基于 imx28 CPU 的定制板 CPU 的串行端口连接到调制解调器的 PCM 输出 我必须为调制解调器的 PCM 接口开发一个驱动程序 使其成为 ALSA SoC 的一部分 您能指出内核树 中与我的设置重新组合的一些驱动程序吗

随机推荐

  • iOS VoiceOver 崩溃(消息发送到已释放的实例)

    在启用 VoiceOver 的情况下运行我的应用程序时 我遇到了奇怪的崩溃 该应用程序有一个侧边栏界面 如 Facebook 当点击其中之一时UITableViewCells 在侧边栏中UITableView 我换出视图控制器 根据点击的单
  • 如何设置 JMenuItem 的大小?

    正如你所看到的 拥有这些东西是很丑陋的JMenuItem是 菜单项的宽度非常小 这是代码 JMenu menuOne new JMenu MenuOne JMenu menuTwo new JMenu MenuTwo JMenu menuT
  • 如何使用 pytest 装置和 django 在unittest中创建类似于“setUp”的方法

    我的测试文件中有下面的代码并尝试重构它 我是 pytest 的新手 我正在尝试实现与 unittest 可用的类似方法 setUp 以便能够将数据库中创建的对象检索到其他函数 而不是重复代码 在这种情况下我想重用month from 测试设
  • @ManyToOne 和 @OneToOne 与 @EmbeddedId 的关系

    我正在尝试将数据库实体的 id 从单个 long 更改为由两个 long 组成的复合 id 这两个 long 封装在我的 ID class 中 如下所示 您会为 ManyToOne 和 OneToMany 关系使用什么注释 我的注释是否有错
  • Capistrano 3:在任务中使用服务器自定义变量

    我有多阶段多服务器设置 在我的任务中我需要使用服务器名称 例如在 stagin rb 我有 set stage staging Define servers server xxx xx xx xxx user deploy roles w
  • 使用Automapper时如何忽略特定类型的属性?

    假设我有两种类型 class Type1 public int Prop1 get set public string Prop2 get set public string Prop3 get set class Type2 public
  • SwiftUI:当 List 和 ForEach 嵌入 TabView 时,WatchOS 8.1 中的 NavigationView 错误

    下面的代码在 WatchOS 7 和 8 0 中运行良好 但现在在 8 1 中 点击该行将导航到目的地 但随后立即导航回根视图 我提交了反馈 FB9727188 并包含以下内容来演示该问题 struct ContentView View S
  • 如何访问 SwiftUI 中的子视图?

    我正在开发 SwiftUI 感觉它与 React 非常相似 刚才我正在自定义一个SwiftUI的Button 遇到一个问题 无法动态访问Button的子视图 以下代码是我要做的 struct FullButton View var acti
  • javascript 原型和闭包中的“this”访问

    我是js初学者 对下面的代码感到困惑 Foo function arg this arg arg Foo prototype init function var f function alert current arg this arg a
  • 添加一个点来扩展多边形而不将其附加到 Google 地图中?

    我正在通过标记在 Google 地图中构建一个多边形 可以拖动这些标记来重塑它的形状 因此 当有 3 个标记时 将绘制多边形 并在形状中附加更多标记 将其扩展 当用户只想遵循简单的顺时针 逆时针模式时 这很好 但是当他想要通过其边缘之一扩展
  • 显示播客列表中的剧集列表

    我正在尝试显示特定作者的播客频道列表 选择播客后 显示相关剧集 我能够独立完成每一项工作 但不知道如何将两者联系起来 现在我的作者播客列表是使用以下命令生成的iTunes 应用商店搜索 API http www apple com itun
  • 用于在输入点和数字后禁止输入点的正则表达式 JavaFX

    我需要输入用逗号分隔的连续整数和实数 如下所示 2 12 4 3 我禁止通过以下表达式连续输入两个逗号 两个点和除数字之外的所有其他字符 2 d 但有了它我可以输入 2 12 4 3 即输入点和数字后 可以再次输入点 且只能是数字或逗号 我
  • Excel 无法在 angularjs 中正确生成

    我在用angularjs并在filesaver js的帮助下使用blob生成excel表我得到了正确的结果 但excel无法在Micrsoft Excel中正确打开 它正在工作 但我没有得到单元格 它显示黑白页面 但内容在那里 帮助如何解决
  • 单元测试 MockHttpServletRequest 不返回内容类型

    我希望应用程序从我的 Java 类返回 JSON 对象 成功和失败情况 我定义了一个 RestControllerAdvice处理来自控制器的错误 我的程序也在json中正确显示错误消息 但问题出在单元测试 问题是当它抛出时 org spr
  • 在没有 gcc 或 root 访问权限的共享主机上安装需要 gcc 的 python 模块

    我正在使用 Hostgator 共享作为生产环境 并且在使用以下命令后安装一些 python 模块时遇到问题 pip 安装 MySQL python 点安装枕头 结果是 无法执行 gcc 权限被拒绝 错误 命令 gcc 失败 退出状态为 1
  • Node/Express 的 MongoDB 示例 AJAX 调用?

    这是从一个非常基本的页面开始 HTML 表单 一个按钮和一个 div 框 单击按钮将通过 AJAX POST 表单数据 数据将存储在 MongoDB 中 并在不刷新页面的情况下检索到 div box 中 来自index html的AJAX
  • VMWare 如何防止虚拟机更新其日期和时间

    我想知道虚拟机 VMWare 如何更新其日期和时间以及如何禁用它 因为我注意到 即使我将虚拟机暂停 关闭一年 当我再次打开它时 它也会有正确的时间和日期 对于物理机 我知道主板上固定的中央单元内有一个小电池 有助于在计算机关闭并断开电源时保
  • Apache Zeppelin 0.6.1:运行 Spark 2.0 Twitter Stream 应用程序

    我有一个安装了 Spark 2 0 和 Zeppelin 0 6 1 的集群 自从上课以来TwitterUtils scala从 Spark 项目移至 Apache Bahir 我无法再在我的 Zeppelin 笔记本中使用 Twitter
  • C# 中实现相等性的最少代码

    In this Eric Lippert 在第 9 点中指出 C 具有 太多的平等性 他指出有 9 或 10 种不同的方法或运算符可以重载以提供对象相等性 我的第一个问题是 如果重写 Object Equals object 方法 编译器是
  • Linux 下 Java 的虚拟内存使用情况,使用了太多内存

    我在 Linux 下运行 Java 应用程序时遇到问题 当我使用默认最大堆大小 64 MB 启动应用程序时 我看到使用 tops 应用程序为该应用程序分配了 240 MB 虚拟内存 这会给计算机上的一些其他软件带来一些问题 而计算机的资源相