Wrapper class caching problem
1 Overview
Hi, everyone, [Java Interview Collection] The daily question is here again. What we are sharing today is: the caching problem of packaging classes.
Our following cases take Integer as an example
2. Performance
public class TestCache { public static void main(String[] args) { Integer i = 127; Integer j = 127; System.out.println(i == j); // true Integer n = 128; Integer m = 128; System.out.println(n == m); // false } }
You can look at the above example, the content assigned in each combination is the same, but the result is: one is true and the other is false.
This in the end is why? ? ? This article will take you to look at the Integer cache problem
3. Analysis
valueOf method
In fact, you can see through the following method that if the passed value is within a certain range, the value will be cached from if, then let us see what low, high, IntegerCache.cache is
public static Integer valueOf(int i) { // Determine whether it is within the scope of the cache if (i >= IntegerCache.low && i <= IntegerCache.high) // fetch value from cache return IntegerCache.cache[i + (-IntegerCache.low)]; // If it is not in the range, directly new the new value return new Integer(i); }
IntegerCache class implementation
From the code below, we can see that our value range is -128 >= i && i <= 127 without additional configuration.
It means that if the value is in the range of -128 >= i && i <= 127, the cached value will be obtained directly, otherwise a new object will be created.
Then let's look at the above example. When the value is 127, it happens to be within this range, so no matter how many times the value is obtained, it is the same object. But beyond this range, it is not necessarily
private static class IntegerCache { // Indicates the minimum value static final int low = -128; // Represents the maximum value of cache access static final int high; // cache object static final Integer cache[]; static { // The default maximum value of the cache pool int h = 127; // Get the maximum value from the configuration String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); // Determine whether it is null if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); // take the maximum value i = Math.max(i, 127); 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; // The default maximum value is 127 - (-128) + 1 = 256 cache = new Integer[(high - low) + 1]; int j = low; // cache the value 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() {} }
4. Q&A
4.1 Question 1
- Q: Are two new Integer 128 equal?
- Answer: No. Because the Integer cache pool defaults to -128-127
4. 2 Question 2
- Q: Can the scope of the Integer cache pool be modified? How to modify?
- Answer: Yes. Use -Djava.lang.Integer.IntegerCache.high=300 to set the Integer cache pool size
4.3 Question 3
- Q: Which design pattern is used for the Integer caching mechanism?
- Answer: Hengyuan model;
4.4 Question 4
- Q: How does Integer get the cache pool size you set?
- Answer: sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
4.5 Question 5
- Q: What is the difference between sun.misc.VM.getSavedProperty and System.getProperty?
- Answer: The only difference is that System.getProperty can only obtain non-internal configuration information; such as java.lang.Integer.IntegerCache.high, sun.zip.disableMemoryMapping, sun.java.launcher.diag, sun.cds.enableSharedLookupCache, etc. cannot be obtained, these can only be obtained using sun.misc.VM.getSavedProperty