4 Replies Latest reply on May 27, 2015 12:22 AM by sumith.puri

    Infinispan - Cache Size through Instrumentation

    sumith.puri

      i have enforced size constraints (in megabytes) on infinispan cache sizes, developed ('invented' ) using 'java instrumentation api as the java agent in wildfly'.

       

      now, everything work fine - including adding, removing elements of cache. but the cache size which is being created is large - whenever i do a cacheContainer.getCache() - it gives me an object that is at least 30+MB in size, when i get another cache using cacheContainer.getCache() - the size goes up by atleast 3.5+ MB everytime.

       

      my questions are:

      1. why is such a large ('heavyweight') object being created by infinispan. is to handle cache dynamics that infinispan instantiates such a heavy object?

      2. i am able to reason out (but not sure) that there may be static fields in the instantiated cache (like around 27+MB everytime) that attribute to this size - from which i understand that it is only a 3MB or 3.5 MB cache object that is being instantiated every time. is this reasoning correct? (i have no way to measure object size without including its static attributes)

       

      also, an important question is that, everytime i reach the size constraint, i am doing the following to force eviction and create some space for newer elements:

      1. is the following a reliable/per-formant way to force cache eviction?

                      LOGGER.warn("Cache Manager does not have space for " + key.toString() + "="
                              + value.toString() + " to " + cachePolicy.getCacheManagerName());
                     
                      // set the configuration to the infinispan cache programmatically
                      Configuration configuration = CacheManagerUtilities.setConfiguration(cachePolicy, cache.size());
                      cache.getCacheManager().defineConfiguration(cache.getName(), configuration);
                     
                      LOGGER.warn("Cache Manager is requesting eviction for "
                              + cachePolicy.getCacheManagerName());
                     
                      // start eviction manually
                      EvictionManager evictionManager = cache.getAdvancedCache().getEvictionManager();
                      evictionManager.processEviction();
                     
                      LOGGER.info("Cache Manager has completed eviction request for "
                              + cachePolicy.getCacheManagerName());
                     
                      // set the configuration to the infinispan cache programmatically
                      configuration = CacheManagerUtilities.setConfiguration(cachePolicy,
                              CacheManagerConstants.CACHE_MANAGER_MAXIMUM_NUMBER_OF_ENTRIES);
                      cache.getCacheManager().defineConfiguration(cache.getName(), configuration);
                     
                      LOGGER.info("Cache Manager has Reset the Configuration for "
                              + cachePolicy.getCacheManagerName());
      
      

       

       

      public static Configuration setConfiguration(CachePolicy cachePolicy, int maxNumberofEntries) {
              return new ConfigurationBuilder().eviction().maxEntries(maxNumberofEntries)
                      .strategy(EvictionStrategy.valueOf(cachePolicy.getCacheManagerEvictionStrategy())).expiration()
                      .lifespan(cachePolicy.getCacheManagerExpirationTime())
                      .wakeUpInterval(cachePolicy.getCacheManagerWakeupInterval())
                      .maxIdle(cachePolicy.getCacheManagerMaxIdleTime()).build();
          }
      
      

       

      Note that CachePolicy is an user-defined object that stores normal cache attributes like max idle time, expiration time, wake up interval and eviction strategy as primitives.

        • 1. Re: Infinispan - Cache Size through Instrumentation
          nadirx

          I'd have to look at your code to understand exactly what is going on, but I wouldn't use instrumentation anywhere, since it is extremely heavyweight and requires you understand how the JVM lays out objects in memory before you get a number which you can reliably use for computation. Infinispan 8 will have size-based eviction using a better (faster) approach: ISPN-5345 Allow eviction for based on approximation of size compared to element count by tristantarrant · Pull Request #…

          • 2. Re: Infinispan - Cache Size through Instrumentation
            sumith.puri

            thanks, tristan.

             

            i did a few tests with the instrumentation api and using a deepSizeOf() implementation available at [JavaSpecialists 142] - Instrumentation Memory Counter i found them to not give reliable and consistent results, like you have mentioned.

             

            for our product, we are using infinispan 7.1.1 and we have implemented our own framework on top of this. We plan to go ahead with max-entries for now. with a roadmap/plan to move to infinispan 8.0.0 as soon as it is available, since we need size semantics. what is the probable release date of infinispan 8.0.0?

            • 3. Re: Infinispan - Cache Size through Instrumentation
              william.burns

              Sumith,

               

              First to continue with the conversation:

               

              As Tristan mentioned the Instrumentation API doing a deep size calculation can be wildly inaccurate if the object being calculated has many child elements that have references back to parent objects as Infinispan does.  The PR that Tristan linked calculates the size of the internal data container only (and only works in 2 cases: key and value are both guaranteed to be byte[] or store as binary is enabled for both keys and values).

               

              It also shouldn't be too hard to add a custom size calculation implementation for the key and value with the new memory based eviction changes.  However this was not done for the first pass through.  I originally thought of adding an Instrumentation jar that could be used as an implementation that did some sort of deep size calculation for each key and value (which would allow for any key/value to be used).  If you are interested in this, please let us know.

               

              To answer some of your questions:

               

              Sumith Puri wrote:

               

              1. is the following a reliable/per-formant way to force cache eviction? - See more at: https://developer.jboss.org/message/931158?et=watches.email.thread#sthash.7IW1NRp0.dpuf

              Calling the [1] method actually has nothing to do with eviction, despite its name.  This was an artifact from before when we didn't always do eviction on the same thread that caused the cache to become to large.  Thus eviction should always be the correct size, this method just removes expired entries from the store and in memory only.

               

              Otherwise the example you have there should be fine.

               

              [1] EvictionManager (Infinispan Distribution 7.2.1.Final API)

              • 4. Re: Infinispan - Cache Size through Instrumentation
                sumith.puri

                thanks, william for providing further details - in continuation of the discussion with tristan.

                 

                kindly go through my blog entry: http://techilashots.blogspot.in/2015/05/deep-size-of-object-java-object-memory.html

                 

                i am planning to develop a standalone memory calculator (i will not start a open source project - but under a "freely downloadable, distributable free open license" - until i find out the exact license which is applicable). this will be on the lines of JAMM - https://github.com/jbellis/jamm. but i will make sure that i do not use any code/artefact from this project - and also will make sure that it is 'most optimized/usable' for cache kind of calculations. since the world of "java memory object anatomy and sizing" is very fuzzy - even though i see many posts on the internet, they do not provide the best approximation of the sizes, as they just do not consider the anatomy as mentioned in my post above. since i started evaluating infinispan and also because our product had a very stringent requirement of allocating by size, it led me to understand the memory model even better. also, it is very intriguing that even with many years of java experience, i suddenly feel 'having no control' over a very primary requirement.


                within a few weeks and as time permits, hopefully i would complete this 'philosophical effort' of understanding the 'java memory object allocation/sizing/anatomy' to its greatest extent. as also, the implementation.


                i/you may later chose to co-ordinate and see if still infinispan may be able to utilize it and if it seriously is the best fit for the requirement. then we can mutually choose to integrate. anything else, do let me know. i will post in reply to this thread - once the code/entry is uploaded on my blog.