2016-02-23 47 views
1

Hazelcast的FREE_HEAP_PERCENTAGE當滿足JVM上的最小配置空閒堆百分比時,最大大小策略不會清除映射條目。Hazelcast FREE_HEAP_PERCENTAGE政策未按預期工作

下面是一個說明這個問題的測試用例。如果測試與其他策略類型(包括USED_HEAP_PERCENTAGE)一起運行,它將按預期工作,以便在達到此最大大小時將條目逐出。但是,如果它與FREE_HEAP_PERCENTAGE一起運行,則儘管事實上免費堆百分比超出了允許的百分比(例如運行管理中心時可以確認),但條目永遠不會從地圖上被逐出。

public class HazelcastMaxSizeTest { 

    private static final String GROUP_NAME = "TEST"; 
    private static final String MAP_NAME = "test"; 

    private static MaxSizeConfig POLICY_THAT_WORKS = new MaxSizeConfig(5, MaxSizeConfig.MaxSizePolicy.USED_HEAP_PERCENTAGE); 
    private static MaxSizeConfig POLICY_THAT_DOES_NOT_WORK = new MaxSizeConfig(99, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_PERCENTAGE); 

    public static void main(String[] args) throws Exception { 

     HazelcastInstance instance = startHazelcast("hazelcast1", POLICY_THAT_DOES_NOT_WORK); 
     System.out.println("started " + instance.getName()); 

     IMap<Long, byte[]> map = createMap(instance, MAP_NAME); 
     System.out.println("map size: " + map.size()); 

     instance.shutdown(); 
    } 

    private static HazelcastInstance startHazelcast(String instanceName, MaxSizeConfig maxSizeConfig) { 

     MapConfig mapConfig = new MapConfig(MAP_NAME); 
     mapConfig.setMaxSizeConfig(maxSizeConfig); 
     mapConfig.setStatisticsEnabled(true); 
     mapConfig.setEvictionPolicy(EvictionPolicy.LRU); 
     mapConfig.setMinEvictionCheckMillis(0L); 
     mapConfig.setBackupCount(1); 

     Config config = new Config(instanceName); 
     config.addMapConfig(mapConfig); 
     config.getManagementCenterConfig().setEnabled(true); 
     config.getManagementCenterConfig().setUrl("http://localhost:8080/mancenter"); 
     config.getGroupConfig().setName(GROUP_NAME).setPassword(GROUP_NAME); 
     return Hazelcast.getOrCreateHazelcastInstance(config); 
    } 

    private static IMap<Long, byte[]> createMap(HazelcastInstance instance, String mapname) { 

     IMap<Long, byte[]> map = instance.getMap(mapname); 

     map.addEntryListener(new EntryEvictedListener<Long, byte[]>() { 

      @Override 
      public void entryEvicted(EntryEvent<Long, byte[]> event) { 
       System.out.println("evicted " + event.getName() + ": " + event.getKey()); 
      } 

     }, false); 

     for (long i = 1; i <= 50_000; i++) { 
      map.set(i, new byte[100]); 
      if (i % 1000 == 0) { 
       System.out.println("set " + map.getName() + ": " + i); 
      } 
     } 

     return map; 
    } 

} 

經過進一步的調試,我想知道如果Hazelcast的EvictionChecker可能會錯誤地計算空閒堆百分比。在調試過程中,我發現計算出的自由堆百分比大於100.它的計算使用available/total,但是如here所述,這應該是available/max而不是?

我的配置或預期使用FREE_HEAP_PERCENTAGE政策有什麼問題嗎?或者這是一個Hazelcast錯誤?

規格:Hazelcast 3.6,-Xmx256m

+0

你的堆大小是多少?我用你的測試,設置-Xmx256m,它爲我工作(可以看到驅逐的消息)。用於測試目的的BTW將minEvictionCheckMillis設置爲零是非常有意義的,通過將其設置爲零,檢查在每個映射#集合上它是否可行。 – mrck

+0

謝謝。我編輯過我的問題,使用'0'作爲'minEvictionCheckMillis'並指定'-Xmx256m',這對我不起作用。但是,我終於可以在顯着增加地圖大小之後獲得'FREE_HEAP_PERCENTAGE'策略以驅逐一些條目。但是,我不明白的是(1)如果USED_HEAP_PERCENTAGE總是以2%(並且至少5%或更多)滿足,爲什麼'FREE_HEAP_PERCENTAGE'未達到99%(或甚至100%)? (2)管理中心顯示堆使用百分比〜30%,那麼爲什麼要滿足99%免費堆的策略呢? – shelley

+0

經過一些進一步的調試之後,我懷疑Hazelcast可能沒有正確計算自由堆。我相應地更新了我的問題。 – shelley

回答

2

進一步調試後,我發現FREE_HEAP_PERCENTAGE政策的意外行爲在可用內存Hazelcast的計算錯誤所致。 Hazelcast的問題跟蹤器中報告此問題爲Issue 7599