Con respecto a mi pregunta anterior, ¿por qué == las comparaciones con Integer.valueOf (String) dan resultados diferentes para 127 y 128? , sabemos que Integer
class
tiene un caché que almacena valores entre -128
y 127
.
Me pregunto, ¿por qué entre -128 y 127 ?
La documentación de Integer.valueOf () indica que " almacena en caché los valores solicitados con frecuencia " . Pero, ¿los valores entre -128
y 127
se solicitan con frecuencia de verdad? Pensé que los valores solicitados con frecuencia son muy subjetivos.
¿Hay alguna posible razón detrás de esto?
De la documentación también se indica: "... y puede almacenar en caché otros valores fuera de este rango " .
¿Cómo se puede lograr esto?
Respuestas:
Me pregunto, ¿por qué entre -128 y 127?
Se puede almacenar en caché un rango mayor de enteros , pero al menos aquellos entre -128 y 127 deben almacenarse en caché porque es un mandato de la Especificación del lenguaje Java (el énfasis es mío):
El fundamento de este requisito se explica en el mismo párrafo:
¿Cómo puedo almacenar en caché otros valores fuera de este rango?
Puede utilizar la
-XX:AutoBoxCacheMax
opción JVM, que no está realmente documentada en la lista de opciones de JVM de Hotspot disponibles . Sin embargo, se menciona en los comentarios dentro de laInteger
clase alrededor de la línea 590 :Tenga en cuenta que esto es específico de la implementación y puede o no estar disponible en otras JVM.
fuente
-128 a 127 es el tamaño predeterminado. Pero javadoc también dice que el tamaño de la caché de Integer puede ser controlado por la
-XX:AutoBoxCacheMax=<size>
opción. Tenga en cuenta que establece solo un valor alto, el valor bajo siempre es -128. Esta característica se introdujo en 1.6.En cuanto a por qué -128 a 127, este es un rango de valores de bytes y es natural usarlo para una caché muy pequeña.
fuente
-XX:AutoBoxCacheMax=<size>
?java -XX:AutoBoxCacheMax=256
en la consola, obtuveError:could not create the Java Virtual Machine
La razón para almacenar en caché los números enteros pequeños, si eso es lo que está preguntando, es que muchos algoritmos utilizan números enteros pequeños en sus cálculos, por lo que suele valer la pena evitar la sobrecarga de creación de objetos para estos valores.
La pregunta entonces es qué enteros almacenar en caché. Una vez más, hablando en general, la frecuencia con la que se usan los valores constantes tiende a disminuir a medida que aumenta el valor absoluto de la constante: todos pasan mucho tiempo usando los valores 1, 2 o 10, relativamente pocos usan el valor 109 muy intensamente menos tendrán rendimiento dependiendo de la rapidez con la que se pueda obtener un entero para 722 .. Java eligió asignar 256 ranuras que abarcan el rango de un valor de byte firmado. Esta decisión puede haberse basado en el análisis de programas existentes en ese momento, pero es igualmente probable que haya sido puramente arbitraria. Es una cantidad razonable de espacio para invertir, se puede acceder rápidamente (máscara para averiguar si el valor está en el rango de la caché, luego una búsqueda rápida en la tabla para acceder a la caché), y definitivamente cubrirá los casos más comunes.
En otras palabras, creo que la respuesta a su pregunta es "no es tan subjetivo como pensaba, pero los límites exactos son en gran medida una decisión práctica ... y la evidencia experimental ha sido que fue lo suficientemente bueno. "
fuente
El valor entero máximo que se puede almacenar en caché se puede configurar a través de la propiedad del sistema, es decir
java.lang.Integer.IntegerCache.high
(-XX:AutoBoxCacheMax
). La caché se implementa mediante una matriz.private static class IntegerCache { static final int high; static final Integer cache[]; static { final int low = -128; // high value may be configured by property int h = 127; if (integerCacheHighPropValue != null) { // Use Long.decode here to avoid invoking methods that // require Integer's autoboxing cache to be initialized int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} }
fuente
Cuando se encuentra con la clase Integer y siempre en un cuadro dentro del rango -128 a 127, siempre es mejor convertir el objeto Integer en un valor int como se muestra a continuación.
fuente