DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Data Engineering
  3. Data
  4. The Internal Cache of Integers

The Internal Cache of Integers

Instances of Integer and other wrapper classes are cached by the JVM for increased performance. Read this post and learn how you can tweak the internal JVM Integer cache to better fit your own needs and potentially gain performance.

Dan Lawesson user avatar by
Dan Lawesson
·
Nov. 18, 16 · Tutorial
Like (39)
Save
Tweet
Share
27.41K Views

Join the DZone community and get the full member experience.

Join For Free

The Internal Cache of Integers

There is an IntegerCache in java.lang.Integer which stores instances for values -128 though 127. This means that Integer.valueOf(17) always will return the very same instance, while Integer.of(200) will not. While this clearly has the advantage of reuse of commonly used Integer values, thus relieving the GC from some work, it also has implications for autoboxing and identity comparisons.

The Cache

An easy way to see the cache in action is to investigate identity for two small integers compared to numbers outside the scope of the cache. The following two statements both hold true.

Integer.valueOf(17) == Integer.valueOf(17)

and

Integer.valueOf(200) != Integer.valueOf(200)

The java.lang.Integer.IntegerCache and Autoboxing

The cache ensures that there is exactly one Integer instance for each of the 256 integer numbers closest to 0. While this may have impact for GC, a more fundamental effect is how this affects autoboxing as can be seen in the following example.

 public class IntegerCacheTest { 

    private static void test(Integer i, Integer i2) { 
        System.out.println(i);
        if (i == i2) System.out.println(" the same"); 
        if (i != i2) System.out.println(" different"); 
        if (i.equals(i2)) System.out.println(" equal"); 
    }

    public static void main(String[] args) {
        test(17, 17);
        test(200, 200);
    }

 } 

Knowing about the caching of instances for integer 17 but not for 200 the reader may already have expected to get differing results for the two comparisons and indeed, the output is as follows.

17
  the same
  equal
200
  different
  equal 

What happens is that 17 and 200 are autoboxed when sent as parameters to a method accepting Integers, but for the lower number the cache will ensure we get the identically same instance while the higher number is outside the size limit of the cache and therefore we get two different but equal instances.

Tweaking the Cache Size

The size of the cache can be tweaked with the -XX:AutoBoxCacheMax= option. Thus, if we run the above program setting the cache size to 1000 by adding -XX:AutoBoxCacheMax=1000 to the VM parameters, we get the following result.

17
  the same
  equal
200
  the same
  equal 

The Cache Internals

The cache is used as follows, as seen in the source code of java.lang.Integer.

 public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
 } 

The actual cache can be found in java.lang.Integer and looks as follows.

 ... 
   private static class IntegerCache {
     static final int low = -128;
     static final int high;
     static final Integer cache[];
     static { // high value may be configured by property
       int h = 127;
       String integerCacheHighPropValue = 
         sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");

       if (integerCacheHighPropValue != null) {
         try {
           int i = parseInt(integerCacheHighPropValue);
           i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE
           h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
         } catch( NumberFormatException nfe) {
           // If the property cannot be parsed into an int, ignore it. 
         } 
       }
       high = h;
       cache = new Integer[(high - low) + 1];
       int j = low;
       for(int k = 0; k < cache.length; k++)
         cache[k] = new Integer(j++);

       // range [-128, 127] must be interned (JLS7 5.1.7)
       assert IntegerCache.high >= 127;
     }

     private IntegerCache() {}

   } ... 

Note how the cache is pre-filled on startup rather than on demand, meaning that the memory footprint of the cache is constant no matter which Integers are actually used in the VM. Tweaking the cache to a very large size thus comes with a steep prize in terms of memory consumption.

Interestingly enough, the parameter to set the size of the cache only affects the upper limit and never the lower, meaning that there is no simple way to get Integers smaller than -128 to be interned in the cache.

Edit: There is a reddit thread about this blog post with valuable feedback. For instance, it is pointed out that new instances of small Integers can still be created with the new operator, a feature that will be deprecated in Java 9.

Cache (computing)

Published at DZone with permission of Dan Lawesson, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Cloud Performance Engineering
  • gRPC on the Client Side
  • Multi-Cloud Integration
  • Container Security: Don't Let Your Guard Down

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: