JVM调优(这里主要是针对优化基于分布式Mahout的推荐引擎)

优化推荐系统的JVM关键参数
-Xmx 设定Java允许使用的最大堆空间。例如-Xmx512m表示堆空间上限为512MB
-server 现代JVM有两个重要标志:-client和-server,分别为客户端程序(运行时间短、占用资源少)和服务器端程序(长时间运行、资源密集型)选择合适的JVM配置。
-d32和-d64 分别设定为32位和64位模式。在一台64位的机器上,两种都是有效的。尽管通常情况下最好是让JVM自己决定,但32位模式可以降低内在需求(例如引用变成4字节)。当然,32位模式下不可能使用超过2~3GB的堆空间(具体取决于JVM),但是如果需求达不到这一界限的话,节省一些内存也不失为一个好的选择。在64位机器上选择32位模式会导致轻微的性能损失。
-XX:+NewRatio= 有一部分堆空间是为生命周期很短的临时对象保留的,不能用于生命周期较长的数据结构。Mahout在运行时是有偏向的:它很少创建临时对象,而生命周期长的对象则需要消耗大量堆空间。默认情况下用于临时对象的堆空间比例太大,这显得有些浪费。此选项可控制用于临时对象的空间比例,例如,设为12时,只有1/12的堆空间用于保存临时对象。注意,此选项是Sum JVM所特有的。

-XX:+UserParallelGC 和

-XX:+UserParallelOldGC

通过并行的垃圾收集机制使JVM更好地利用多个处理器或单一处理器的多个核。当可用的处理器核不止一个时,这会允许垃圾收集与主计算过程并行执行。

   基于一个例子演示这些JVM配置项的效果。下面这个intro.csv文件有几千万条记录

DataModel model=new FileDataModel(new File("intro.csv")); //.csv是逗号文件

UserSimilarity similarity=new PearsonCorrelationSimilarity(model);

UserNeighborhood neighborhood=new nearestNUserNeighborhood(2,similarity,model);

Recommender recommender=new GenericUserBasedRecommender(model,neighborhood,similarity);

LoadEvaluator.runLoad(recommender);

  运行这段代码,首先从默认的32位客户端JVM开始:-client -d32 -Xmx512m。我们使用一个64位计算机进行测试,负载评估结果显示推荐时间为425ms,稳定状态需要消耗248MB堆空间。

  将-client改为-server。测试结果显示,内存用量没有变化,但推荐时间降为192ms。这表明为服务器端模式优化的JVM更适合此类应用。

  现在,将-d32改为-d64。遇到了OutOfMemoryError错误。将-Xmx512m改为-Xmx768m,分配768MB的堆空间,再次运行。推荐速度再次提升,时间降至142ms。稳定状态下的内存需求则几乎没变:256MB。从设计上讲,64位模式增加的内存需求用在对象和引用上,而与Mahout的推荐引擎创建的的长时对象关系不大。

  大家可能会有疑问,既然稳定状态下的内在需求仅为256MB,为什么在可用内存为512MB的情况下,会因为堆空间不足而出错?因为在构建DataModel的

in-memory数据表示过程中,内存需求会有一个峰值。

  尝试-XX:+NewRatio=12标志,它会将内存用量降至640MB。

  最后,试试加上-XX:+UserParallelGC 和-XX:+UserParallelOldGC。当可用的处理器核不止一个时,会允许垃圾收集与主计算过程并行执行。在我们的测试机器上,推荐时间降至126ms。

做个小推广:程序员经常久坐,颈椎毛病比较多,特别推荐ventry颈椎保健枕