background image

  在较大的 Java Heap 和较小的本地 Heap 比赛中,32 位虚拟机可能会变得相当棘
手。试图在一个 32 位 VM 如 2.5GB+上设置一个大型堆,根据应用程序占用和线程数量
等因素会增加 OutOfMemoryError 这个异常抛出。64 位 JVM 可以解决这个问题,但物
理资源可用性和垃圾回收成本仍然是有限制的(成本主要集中在 GC 大小收集上)。最大并
不表示是最好的,所以请不要假设在一个 16GB 的 64 位虚拟机上可以运行 20 个 Java 
EE 应用程序。
  2.数据和应用程序为王:回顾静态占用需求
  应用程序以及相关数据将决定 Java

堆空间占用需求。通过静态内存,可 预测 下面

的内存需求:

• 

   确定将会有多少不同的应用程序部署到预先计划的一个单独的 JVM 进程上,例如
有多少个 ear 文件、war 文件、jar 文件等。在一个 JVM 上部署的应用程序越多,对本机堆
的需求就越多。

• 

   确定有多少个类需要在运行时加载:包括第三方 API。越多的类加载器和类在运行
时被加载,在 HotSpot VM PermGen 空间和内部 JIT 相关优化对象上的需求就越高。

• 

   确定数据缓存占用,如应用程序加载内部缓存数据结构(和第三方 API),例如数据
库中的数据缓存,从文件中读取数据等。数据缓存使用越多,Java Heap OldGen 空间需
求就越高。

• 

   确定允许建立的中间件线程数量。这是非常重要的,因为 Java 线程需要足够的本
机内存,否则会抛 OutOfMemoryError 异常。
  在 JVM 进程上部署的应用程序越多,对本地内存和 PermGen 空间的要求就越高。数
据缓存并不是序列化为一个磁盘或数据库,它将从 OldGen 空间里面需要额外的内存。
  设法对静态内存占用进行合理的评估,在真正进行数据测试之前,设置一些 JVM 能
力 起 点 是 非 常 有 用 的 。 对 于 32 位 JVM, 通 常 不 推 荐 一 个 Java 堆 大 小 超 过 2 GB(-
Xms2048m,-Xmx2048m),对于 Java EE 应用程序和线程来说这样将需要足够的内存
和本机堆 PermGen。
  这个评估是非常重要因为太多的应用程序部署在一个 32 位 JVM 进程上很容易导致
本机堆耗尽;尤其是在多重线程环境。

对于 64 位 JVM  

, 一个 3GB 或者 4GB 的 Java 堆/JVM 进程是推荐的起点。

 3.业务流量设置规则:审查动态内存占用需求
  业务流量通常会决定动态内存占用。通过观察各种监控工具可以发现并发用户与

请求生成的 JVM GC“

心跳 ,这是由于频繁的创建和垃圾回收短期或者长期对象。

  一个典型的 32 位 JVM,Java 堆大小设置在 2 GB(使用分代&并发收集器)通常

为 500 MB YoungGen 分配空间和 1.5 GB 的 OldGen 空间。

  最大限度地减少重大 GC 收集的频率是获得最佳性能的关键因素,所以在高峰

的时候理解和评估需要多少内存是非常重要的。

  再次声明,应用程序类型和数据将决定内存需求。购物车的应用程序类型 (长期

居住的对象)涉及大型和非序列化会话数据,这个通常需要大型 Java 堆和很多 OldGen
空间。无状态和 XML 处理(很多短命的对象)繁重的应用程序需要适当 YoungGen 空间,
以尽量减少频率主要集合。

  例如:
  你有 5 个 ear 应用程序(2000 多个 Java 类)要部署(包含中间件代码)

• 

   本地堆需求估计为 1GB(必须足够大以处理线程创建等等。)PermGen 空间大

约是 512 MB。