Java: ¿las matrices 1-d siempre son contiguas en la memoria?

5 minutos de lectura

Muchos libros/artículos que he leído sobre este tema, así como un pequeño programa que escribí usando ‘Inseguro’, indican que las matrices 1-d en Java siempre son contiguas en la memoria. Entonces, ¿lo dicta JLS o es una convención de implementación? La pregunta se hace para confirmar esta indicación.

No, la especificación JVM no tiene tales garantías:
http://docs.oracle.com/javase/specs/jvms/se5.0/html/Concepts.doc.html#16446

En la práctica, probablemente sea el caso, pero tampoco tiene garantía sobre el tamaño de la palabra.

Unsafe no es una clase estándar de Java, por lo que si su programa usa esto, entonces no es portátil de todos modos…

avatar de usuario
gustar

Quiero refrescar esta pregunta con lo que La especificación del lenguaje Java, Java SE 8 Edition (JLS) y La especificación de máquina virtual de Java, Java SE 8 Edition (JVMS) están diciendo al respecto.

Tenemos dos opciones para responder a esta pregunta:

  1. Qué restricciones se imponen a las implementaciones de JVM. Este es el enfoque más confiable porque la implementación de cualquier especificación supone inherentemente “Todo lo que no está prohibido está permitido” principio.
  2. Lo que la mayoría de las implementaciones de JVM sugieren razonable.

Señalaré las restricciones de especificación.

si miramos Capítulo 10. Matrices del JLS (y cualquier otro capítulo de JLS y JVMS relacionado con arreglos) no pudimos encontrar ninguna mención de las restricciones de diseño de memoria impuestas a los arreglos. Por lo tanto, definitivamente significa que la matriz podría no ser continua.

Además, JLS dice que las matrices son objetos:

Capítulo 10. Matrices.

En el lenguaje de programación Java, las matrices son objetos (§4.3.1), se crean dinámicamente y pueden asignarse a variables de tipo Objeto (§4.3.2). Todos los métodos de la clase Object pueden invocarse en una matriz. …

4.3.1. Objetos.

Un objeto es una instancia de clase o una matriz. (y Array es Objeto)

Y al mismo tiempo, JVMS dice que los objetos y las matrices se almacenan en el montón:

2.5.3. Montón

La máquina virtual de Java tiene un montón que se comparte entre todos los subprocesos de la máquina virtual de Java. El montón es el área de datos en tiempo de ejecución desde la cual se asigna la memoria para todas las instancias de clase y matrices.

Pero JVMS no obliga a que la memoria del montón sea continua:

2.5.3. Montón

… La memoria del montón no necesita ser continua.

Como todas las matrices se almacenan en montón y el montón puede no ser continuo, se deduce que las matrices también pueden no ser continuas.

  • Solo una nota: ¿Cuándo se debe usar el formato de código para texto sin código? :).

    – Tomás

    25 de julio de 2015 a las 8:59

  • ¿Cómo haría las citas similares de la especificación oficial? Quiero aislarlos de otros textos para una mejor lectura.

    – me gusta

    25 de julio de 2015 a las 9:09

  • Tenga en cuenta la diferencia entre “formato de código” y “cita en bloque”. Palabras como “JLS”, “JVMS” y “Capítulo 10. Matrices”. no son código y deben formatearse como tales :). Las citas son correctas.

    – Tomás

    25 de julio de 2015 a las 9:21


  • No se sigue de que todo el montón no sea contiguo que cualquier objeto específico no pueda ser contiguo. Esto podría ser un hecho, pero no se sigue de esta premisa, ni tampoco del hecho de que los arreglos sean objetos.

    – usuario207421

    18 sep 2021 a las 8:00


Dado que no hay una forma real de interactuar con las direcciones de memoria en Java, tampoco está definido en la especificación cómo se ve el diseño del objeto en la memoria.

Tenga en cuenta que usando Unsafe casi automáticamente significa que estás paseando fuera del ámbito de la especificación.

Dicho esto, me atrevería a decir que la mayoría de las implementaciones de JVM hacer de hecho, use un diseño lineal para matrices (unidimensionales).

  • Es interesante que Java permita el código “Inseguro” en este contexto pero no proporcione la palabra clave goto.

    – nicomp

    18 de septiembre de 2021 a las 13:38

  • @icomp: Java no permite Inseguro. De hecho, no es parte de la plataforma. Es un detalle de implementación de una implementación específica. De hecho, desapareció en las versiones más nuevas de Java (todavía se usa internamente de una forma u otra, pero es inaccesible para el código de usuario). Goto sería un desastre en Java, porque básicamente rompe cualquier predicción estática de cómo se permite que se vea la pila en cualquier punto dado en la ejecución del método, que es una parte importante de la verificación del código de bytes (es decir, verificar que los métodos son sensatos) .

    – Joaquín Sauer

    18 sep 2021 a las 13:59

Dado que muchas JVM tienen el requisito de que el montón sea continuo en la memoria, creo que es poco probable que coloquen una matriz 1d de primitivos en diferentes lugares de la memoria.

El objeto al que hace referencia un objeto.[] es poco probable que sean continuos en la memoria e incluso si lo son, se pueden reorganizar sin previo aviso.

Nota: Usando Unsafe puede leer referencias en una matriz como int valores para ver cuáles son antes y después de un GC. Algunas JVM usan referencias de 64 bits que requieren mucho tiempo, pero la mayoría usa referencias de 32 bti (incluso para JVM de 64 bits)

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad