2012-06-21 16 views
14

En esta blog post, se dice que el uso de memoria mínima de una cadena es:¿Por qué se dice que el uso de la memoria String de Java es alto?

8 * (int) ((((no chars) * 2) + 45)/8) bytes.

Por lo tanto, para el String "Apple Computers", el uso mínimo de memoria sería de 72 bytes.
Incluso si tengo 10,000 objetos String de dos veces esa longitud, el uso de la memoria sería menos de 2Mb, que no es mucho. Entonces, ¿eso significa que estoy subestimando la cantidad de cadenas presentes en una aplicación empresarial, o esa fórmula es incorrecta?

Gracias

Respuesta

16

El almacenamiento de cadenas en Java depende de cómo se obtuvo la cadena. La matriz char de respaldo se puede compartir entre varias instancias. Si ese no es el caso, tiene la sobrecarga de objetos habitual más el almacenamiento para un puntero y tres int s, que generalmente salen a una sobrecarga de 16 bytes. A continuación, la matriz de respaldo requiere 2 bytes por char ya que char s son unidades de código UTF-16.

Para "Apple Computers" donde la matriz de soporte no es compartida, el costo mínimo va a ser

  1. matriz de soporte para 16 caracteres - 32B que se alinea muy bien en un límite de palabra.
  2. puntero a matriz - 4 o 8B dependiendo de la plataforma
  3. tres int s para el desplazamiento, la longitud y código hash memoized - 12B
  4. 2 x objeto overhead - depende de la VM, pero 8B es una buena regla de pulgar.
  5. uno int para la longitud del conjunto.

Aproximadamente 72B de los cuales la carga real constituye el 44.4%. La carga útil constituye más para cadenas más largas.


En Java7, algunas implementaciones de JDK son doing away with backing array sharing para evitar el fijar grandes char [] s en la memoria. Eso les permite eliminar 2 de los tres int s.

Eso cambia el cálculo a 64B para una cadena de longitud 16 de la cual la carga real constituye el 50%.

1

En comparación con otros tipos de datos a que usted tiene, definitivamente es alta. Las otras primitivas usan 32 bits, 64 bits, etc.

Y dado que String es inmutable, cada vez que realiza alguna operación en él, termina creando un nuevo objeto String, consumiendo aún más memoria.

+1

Dado que String es inmutable, las operaciones que realice en él realmente pueden * ahorrar * espacio, porque las cadenas pueden compartir memoria. – Thilo

+0

Pero cada vez que creas un nuevo objeto 'String', ¿no ocuparía más memoria? –

+0

Las primitivas usan 32 bytes? Creo que te refieres a bits. :) – Makoto

3

¿Es posible guardar datos de caracteres usando menos memoria que una cadena Java? Sí.

¿Importa para aplicaciones "empresariales" (o incluso aplicaciones Android o J2ME, que tienen que pasar por mucha menos memoria)? Casi nunca.

La optimización prematura es la raíz ...

+1

+1 para la optimización prematura. – Makoto

Cuestiones relacionadas