从 Java 代码到 Java 堆 理解和优化您的应用程序的内存使用

从 Java 代码到 Java 堆

理解和优化您的应用程序的内存使用

https://www.ibm.com/developerworks/cn/java/j-codetoheap/

 

优化应用程序代码的内存使用并不是一个新主题,但是人们通常并没有很好地理解这个主题。本文将简要介绍 Java 进程的内存使用,随后深入探讨您编写的 Java 代码的内存使用。最后,本文将展示提高代码内存效率的方法,特别强调了 HashMapArrayList 等 Java 集合的使用。

背景信息:Java 进程的内存使用

参考知识

如需进一步了解 Java 应用程序的进程内存使用,请参阅 Andrew Hall 撰写的 developerWorks 文章 “内存详解”。这篇文章介绍了 内存详解 以及 AIX® 提供的布局和用户空间,以及 Java 堆和本机堆之间的交互。

通过在命令行中执行 java 或者启动某种基于 Java 的中间件来运行 Java 应用程序时,Java 运行时会创建一个操作系统进程,就像您运行基于 C 的程序时那样。实际上,大多数 JVM 都是用 C 或者 C++ 语言编写的。作为操作系统进程,Java 运行时面临着与其他进程完全相同的内存限制:架构提供的寻址能力以及操作系统提供的用户空间。

架构提供的内存寻址能力依赖于处理器的位数,举例来说,32 位或者 64 位,对于大型机来说,还有 31 位。进程能够处理的位数决定了处理器能寻址的内存范围:32 位提供了 2^32 的可寻址范围,也就是 4,294,967,296 位,或者说 4GB。而 64 位处理器的可寻址范围明显增大:2^64,也就是 18,446,744,073,709,551,616,或者说 16 exabyte(百亿亿字节)。

处理器架构提供的部分可寻址范围由 OS 本身占用,提供给操作系统内核以及 C 运行时(对于使用 C 或者 C++ 编写的 JVM 而言)。OS 和 C 运行时占用的内存数量取决于所用的 OS,但通常数量较大:Windows 默认占用的内存是 2GB。剩余的可寻址空间(用术语来表示就是用户空间 )就是可供运行的实际进程使用的内存。

对于 Java 应用程序,用户空间是 Java 进程占用的内存,实际上包含两个池:Java 堆和本机 (非 Java)堆。Java 堆的大小由 JVM 的 Java 堆设置控制:-Xms-Xmx 分别设置最小和最大 Java 堆。在按照最大的大小设置分配了 Java 堆之后,剩下的用户空间就是本机堆。图 1 展示了一个 32 位 Java 进程的内存布局:


图 1. 一个 32 位 Java 进程的内存布局示例
一个 32 位 Java 进程的内存布局示例视图

图 1 中,可寻址范围总共有 4GB,OS 和 C 运行时大约占用了其中的 1GB,Java 堆占用了将近 2GB,本机堆占用了其他部分。请注意,JVM 本身也要占用内存,就像 OS 内核和 C 运行时一样,而 JVM 占用的内存是本机堆的子集。

Java 对象详解

在您的 Java 代码使用 new 操作符创建一个 Java 对象的实例时,实际上分配的数据要比您想的多得多。例如,一个 int 值与一个 Integer 对象(能包含 int 值的最小对象)的大小比率是 1:4,这个比率可能会让您感到吃惊。额外的开销源于 JVM 用于描述 Java 对象的元数据,在本例中也就是 Integer

根据 JVM 的版本和供应的不同,对象元数据的数量也各有不同,但其中通常包括:

  • :一个指向类信息的指针,描述了对象类型。举例来说,对于 java.lang.Integer 对象,这是 java.lang.Integer 类的一个指针。
  • 标记 :一组标记,描述了对象的状态,包括对象的散列码(如果有),以及对象的形状 (也就是说,对象是否是数组)。
  • :对象的同步信息,也就是说,对象目前是否正在同步。

对象元数据后紧跟着对象数据本身,包括对象实例中存储的字段。对于 java.lang.Integer 对象,这就是一个 int

如果您正在运行一个 32 位 JVM,那么在创建 java.lang.Integer 对象实例时,对象的布局可能如图 2 所示:


图 2. 一个 32 位 Java 进程的 java.lang.Integer 对象的布局示例
一个 32 位 Java 进程的 java.lang.Integer 对象的布局示例

图 2 所示,有 128 位的数据被占用,其中用于存储 int 值的为 32 位,而对象元数据占用了其余的 96 位。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值