IBM i 上 Java Break Memory 介绍与问题分析2014-08-09 IBM 高 山, 高 丽,相 云
引言
很多使用 IBM Java 虚拟机的用户常常有这样一个疑问:我的程序是应该用 32 位 JVM,还是选择 64 位 JVM?我们知道 , 和 64 位 JVM 相比,32 位 JVM 具有如下优点:启动速度快运行速度快对同一应用而言,占用的系统资源少显而易见 , 32 位 JVM 是用户的首选。但是 , 采用 32 位寻址 , 32 位 JVM 的可用的内存空间远比 64 位的小得多 , 所以有些时候用户不得不使用 64 位 JVM。用户常会问这样的问题 : 我的 Java 作业究竟需要多少内存 ?要回答这一问题,首先要弄清楚 Java 作业的内存结构。Java 应用程序运行时占用的内存包括两部分:Java Heap 和 Break Memory。 相比较而言,Java Heap 是一个熟悉的术语,它是指对为 Java Object 所准备的空间, 这些 Java Object 会由 JVM 的垃圾回收机制所管理。Break Memory 也是 JVM 内存方面的一个术语 。本文主要讨论 Break Memory,同时介绍 IBM i 上 JVM 的内存分配模型以及如何判断问题是 Break Memory 上的 OutOfMemory。
什么是 Break memory
相对 Heap Memory 而言,Break Memory 又叫内部内存或私有内存 . Break Memory 是在 JVM 中通过 malloc 方式申请的空间 , 具体来说 , 它由如下几个部分使用 :Thread StacksJVM 的 C/C++ 代码用户的 Native 函数代码及 Pase 的 Native 函数为了更好的理解内存结构 , 下面给出了 32bit 内存空间图表 ( 表 1):在这个图表中可以看到 , 程序的内存被分成 16 个分区 , 每个分区是 256M, 这样一个程序共占用 256*16 = 4G 空间。程序内存的这种布局有如下特性 :有几个内存分区是被预先安排为其他用途 , 这几个分区是不能作为 Java Heap 或 Break Memory 使用的。Heap Memory 和 Break Memory 使用的空间总额是固定的 , 它们共同占用这些区间 . 在表 1 上 , 从 0x3 到 0xC 是 Break Memory 和 Heap Memory 的空间 . Break Memory 从 0x3 分区开始分配空间 , 而从 0xC 分区按照分区反方向预先保留出来内存空间将留给 Heap Memory 使用 . Heap Memory 预先保留占用的分区越多 , Break Memory 能使用的分区就越少 , 反之亦然 .当一个分区其中的任何一部分用做 Heap Memory,则整个分区都将保留下来做这个特定用途使用 , Break Memory 不能再使用这一分区。在 JVM 启动的时候 , 可以设定为 Heap Memory 所保留的最大内存空间(-Xmx), 默认是 2GB。很多时候 , 程序并没有设定 Heap Memory 大小 . 在这种默认情况下 , 内存的分配布局是 :Heap Memory 占用 8 个分区 , 2048M. (2048 / 256 = 8)为运行 JVM 有 6 个内存分区做其它方面的用途 , 包括内核 , 应用程序文本 , 栈数据 , 共享类库文本 , 等等 .剩下 2 个内存分区留给 Break Memory: (16 total) - (8 heap) - (6 reserved) = 2另一种常见的情况是设定 Heap Memory 最大为 1500M, 此时 :Heap Memory 一共占用 6 个分区 , (1500 / 256 = 5.8)同上面一样 , 有 6 个内存分区做其它方面的用途剩下 4 个分区 (1024 MB) 留给 Break 内存
图 1. 标准模式