在高性能硬件上部署程序,目前主要有两种方式:
- 通过64位JDK来使用大内存
- 使用若干32位虚拟机建立逻辑集群来利用硬件资源
其中第一种方案,给Java虚拟机分配超大堆的前提是有把握把应用程序的Full GC频率控制得足够低,至少要不影响到用户使用,比如一天出现一次,那么就可以在深夜执行定时任务的当时触发Full GC(关于手动触发Full GC方式 jmap -histo:live <LVMID>)甚至可以重启服务来保持内存空间可以维持在一个稳定的水平。
控制Full GC频率的关键是看应用中绝大多数对象能否符合“朝生夕灭”的原则,即大多数对象的生存时间不应太长,尤其是不能有成批的、长时间的大对象产生,这样老年代空间才能稳定,Full GC的平率降低。
大多数网站形式的应用中里,主要对象的生存周期都应该是请求级(request)或者页面级,会话级(session)和全局级(application)的长生命对象相对很少。
计划使用64位JDK来管理内存,还需要考虑如下问题:
- 内存回收导致的长时间停顿
- 现阶段,64位JDK的性能测试普遍低于32位的JDK
- 需要保证程序足够稳定,因为这种应用要是产生堆溢出几乎就无法产生堆转储快照(因为占用存储太大),即便产生也无法分析
- 相同程序在64位JDK消耗的内存一般比32位JDK大,这是由于指针膨胀(在32位虚拟机中,本地指针占用4字节,在64位虚拟机中本地指针占用8字节),以及数据类型对齐补白等因素导致的。