El montón y la pila Java en Java divide la memoria en dos tipos: uno es la memoria de la pila y la otra es la memoria del montón.
Algunos tipos básicos de variables definidas en funciones y variables de referencia de objetos se asignan en la memoria de la pila de la función. Cuando una variable se define en un bloque de código, Java asigna el espacio de memoria para la variable en la pila. Cuando el alcance de la variable excede el alcance de la variable, Java liberará automáticamente el espacio de memoria asignado para la variable, y el espacio de memoria se puede usar por separado de inmediato.
La memoria Heap se usa para almacenar objetos y matrices creados por New. La memoria asignada en el montón es administrada por el recolector de basura automática de la máquina virtual Java. Después de generar una matriz u objeto en el montón, se puede definir una variable especial en la pila. El valor de esta variable es igual a la primera dirección de la matriz u objeto en la memoria del montón. Esta variable especial en la pila se convierte en una variable de referencia para la matriz u objeto. En el futuro, puede usar la variable de referencia en la memoria de pila en el programa para acceder a la matriz u objeto en el montón. La variable de referencia es equivalente a un alias o nombre de código para la matriz u objeto.
Las variables de referencia son variables ordinarias. Cuando se define, la memoria se asigna en la pila. Las variables de referencia se lanzan fuera del alcance cuando se ejecuta el programa. La matriz y el objeto en sí se asignan en el montón. Incluso si el programa se ejecuta fuera del bloque de código donde las declaraciones que usan nuevas para generar la matriz y el objeto se encuentran, la memoria del montón ocupada por la matriz y el objeto en sí no se lanzarán. La matriz y el objeto solo se convierten en basura cuando no hay una variable de referencia que le apunte, y ya no se puede usar, sino que aún ocupan la memoria y el recolector de basura libera en un momento incierto. Esta es también la razón principal por la que Java toma más memoria. De hecho, las variables en la pila apuntan a variables en la memoria de montón, ¡que es el puntero en Java!
Montón y pila en java
Java divide la memoria en dos tipos: uno es la memoria de la pila y la otra es la memoria de montón.
1. Stack y Heap son ambos lugares utilizados por Java para almacenar datos en la RAM. A diferencia de C ++, Java administra automáticamente pilas y montones, y los programadores no pueden configurar pilas o montones directamente.
2. La ventaja de la pila es que la velocidad de acceso es más rápida que el montón, solo solo de los registros ubicados directamente en la CPU. Pero la desventaja es que el tamaño de los datos y la vida útil en la pila deben ser deterministas y carecer de flexibilidad. Además, se pueden compartir datos de pila. La ventaja del montón es que puede asignar dinámicamente el tamaño de la memoria, y la vida útil no tiene que ser contada al compilador de antemano. El recolector de basura de Java recopilará automáticamente los datos que ya no se usan. Pero la desventaja es que la memoria debe asignarse dinámicamente en tiempo de ejecución, la velocidad de acceso es más lenta.
3. Hay dos tipos de datos en Java.
Uno son los tipos básicos (tipos primitivos), hay 8 tipos, a saber, int, corto, largo, byte, flotación, doble, booleano, char (nota,
No hay un tipo básico de cadena). Este tipo de definición se define mediante una forma como int a = 3; largo B = 255L; y se llama variable automática. Vale la pena señalar que la variable automática contiene valores literales, no instancias de la clase, es decir, no referencias a la clase, y no hay clase aquí. Por ejemplo, int a = 3; Aquí A es una referencia que apunta al tipo int,
Apunte al valor literal de 3. Debido al tamaño de estos valores litentes, se puede conocer la vida útil de estos valores litentes (estos valores literal se definen fijamente en un bloque de programa, y después del bloqueo del programa sale, el valor de campo desaparece).
En aras de seguir la velocidad, existe en la pila.
Además, una característica especial muy importante de la pila es que los datos en la pila se pueden compartir. Supongamos que definimos al mismo tiempo:
int a = 3;
int b = 3;
El compilador primero procesa int a = 3; Primero, creará una referencia a la variable A en la pila, y luego averigüe si hay una dirección con un valor literal de 3. Si no se encuentra, abrirá una dirección con el valor literal de 3, y luego señale A a la dirección de 3. Luego procese int b = 3; Después de crear la variable de referencia de B, ya que ya hay un valor literal de 3 en la pila, B se apunta directamente a la dirección de 3. De esta manera, A y B apuntan a 3 al mismo tiempo.
Es particularmente importante tener en cuenta que esta referencia literal es diferente a la de los objetos de clase. Suponiendo que las referencias de dos objetos de clase apunten a un objeto al mismo tiempo, si una variable de referencia del objeto cambia el estado interno del objeto, la otra variable de referencia del objeto refleja inmediatamente este cambio. En cambio, modificar su valor a través de una referencia literal no hará que otro valor se cambie en consecuencia. Como en el ejemplo anterior, después de definir los valores de A y B, deje a = 4; Entonces, B no será igual a 4, o igual a 3. Dentro del compilador, cuando se encuentre a = 4, volverá a buscar si hay un valor literal de 4 en la pila. Si no, vuelva a abrir la dirección para almacenar el valor de 4; Si ya existe, apunte directamente a esta dirección. Por lo tanto, el cambio en el valor A no afectará el valor b.
Otro tipo son los datos de la clase de empaque, como entero, cadena, doble, etc. que envuelve los tipos de datos básicos correspondientes. Todos estos datos de clase existen en el montón. Java usa la instrucción nueva () para mostrar el compilador y solo crea dinámicamente según sea necesario en el tiempo de ejecución, por lo que es más flexible, pero la desventaja es que toma más tiempo.
En Java, hay seis lugares diferentes donde se pueden almacenar datos:
1. Registrarse. Esta es el área de almacenamiento más rápida porque se encuentra en un lugar diferente a otras áreas de almacenamiento: el procesador. Sin embargo, el número de registros es extremadamente limitado, por lo que los registros son asignados por el compilador de acuerdo con los requisitos. No puede controlarlo directamente, ni puede sentir signos de la existencia del registro en el programa.
2. Pila. Ubicado en RAM de propósito general, pero con su "puntero de pila" puede obtener soporte del procesador. Si el puntero de la pila se mueve hacia abajo, se asigna una nueva memoria; Si se mueve hacia arriba, esa memoria se libera. Esta es una forma rápida y eficiente de asignar el almacenamiento, solo superado por los registros. Al crear un programa, el compilador Java debe conocer el tamaño exacto y el ciclo de vida de todos los datos almacenados en la pila, ya que debe generar el código correspondiente para mover el puntero de la pila hacia arriba y hacia abajo. Esta restricción limita la flexibilidad del programa, por lo que aunque algunos datos JA VA se almacenan en la pila, especialmente las referencias de objetos, los objetos Java no se almacenan en él.
3. Montón. Un grupo de memoria universal (también existe en RAM) para almacenar los llamados objetos Java. La ventaja del montón es que el compilador no necesita saber cuántas áreas de almacenamiento se asignan desde el montón, ni necesita saber cuánto tiempo durarán los datos almacenados en el montón. Por lo tanto, existe una gran flexibilidad en la asignación de almacenamiento en el montón. Cuando necesita crear un objeto, solo necesita escribir una línea simple de código en nuevo. Al ejecutar esta línea de código, se almacenará automáticamente y asignará en el montón. Por supuesto, se debe pagar el código correspondiente por esta flexibilidad. Se necesita más tiempo para asignar el almacenamiento con el montón que almacenarlo con la pila.
4. Almacenamiento estático. "estático" aquí significa "en una posición fija". El almacenamiento estático almacena datos que siempre han existido cuando el programa se está ejecutando. Puede usar la palabra clave estática para identificar que un elemento específico de un objeto es estático, pero el objeto Java en sí nunca se almacena en el espacio de almacenamiento estático.
5. Almacenamiento constante. Los valores constantes generalmente se almacenan directamente dentro del código del programa, y es seguro hacerlo porque nunca se cambiarán. A veces, en un sistema incrustado, la constante en sí misma se separa de otras partes, por lo que en este caso, es opcional ponerla en la ROM.
6. Almacenamiento no RAM. Si los datos sobreviven completamente fuera del programa, se puede dejar sin ningún control del programa y puede existir cuando el programa no se está ejecutando.
En términos de velocidad, hay una relación de la siguiente manera:
Regístrese <Stack <Heap <Otro
"El pasaje anterior se extrae de" Pensamiento en Java ""
Pregunta 1:
Cadena str1 = "ABC"; Cadena str2 = "ABC"; System.out.println (str1 == str2); //verdadero
Pregunta 2:
Cadena str1 = nueva cadena ("ABC"); Cadena str2 = nueva cadena ("ABC"); System.out.println (str1 == str2); // FALSO Pregunta 3:
Cadena s1 = "ja"; Cadena s2 = "VA"; Cadena s3 = "java"; Cadena S4 = S1 + S2; System.out.println (S3 == S4); // false System.out.println (S3.Equals (S4)); // Verdadero
Algunos tipos básicos de variables definidas en la función y las variables de referencia del objeto se asignan en la memoria de la pila de la función.
Cuando una variable se define en un bloque de código, Java asigna el espacio de memoria para esta variable en la pila. Cuando el alcance de la variable excede la variable, Java liberará automáticamente el espacio de memoria asignado para la variable, y el espacio de memoria se puede usar por separado de inmediato.
La memoria Heap se usa para almacenar objetos y matrices creados por New.
La memoria asignada en el montón es administrada por el colector de basura automático de la máquina virtual de Java.
Después de generar una matriz u objeto en el montón, se puede definir una variable especial en la pila, de modo que el valor de esta variable en la pila es igual a la primera dirección de la matriz u objeto en la memoria del montón, y la variable en la pila se convierte en una variable de referencia para la matriz u objeto.
Una variable de referencia es equivalente a un nombre dado a una matriz u objeto. Puede usar las variables de referencia en la pila en el programa para acceder a la matriz u objeto en el montón.
Específicamente: la pila y el montón son ambos lugares utilizados por Java para almacenar datos en la RAM. A diferencia de C ++, Java administra automáticamente pilas y montones, y los programadores no pueden configurar pilas o montones directamente.
El montón Java es un área de datos de tiempo de ejecución, desde el cual los objetos asignan el espacio. Estos objetos se establecen a través de instrucciones como New, NewArray, Anewarray y MultianewArray. No requieren que el código del programa se publique explícitamente. El montón es responsable de la recolección de basura. La ventaja del montón es que puede asignar dinámicamente el tamaño de la memoria, y la vida útil no tiene que ser contada al compilador de antemano, porque asigna dinámicamente la memoria en tiempo de ejecución. El recolector de basura de Java recopilará automáticamente los datos que ya no se usan. Pero la desventaja es que debido a que necesita asignar dinámicamente la memoria en tiempo de ejecución, la velocidad de acceso es más lenta.
La ventaja de la pila es que la velocidad de acceso es más rápida que el montón, solo solo de los registros, y los datos de la pila se pueden compartir. Pero la desventaja es que el tamaño de los datos y la vida útil en la pila deben ser deterministas y carecer de flexibilidad. La pila almacena principalmente algunos tipos básicos de variables (, int, corta, larga, byte, flotante, doble, booleana, char) y manijas de objetos.
Una característica especial muy importante de la pila es que los datos existentes en la pila se pueden compartir. Supongamos que definimos al mismo tiempo:
int a = 3;
int b = 3;
El compilador primero procesa int a = 3; Primero, creará una referencia en la pila con una variable A, y luego descubrirá si hay un valor de 3 en la pila. Si no se encuentra, almacenará 3 y luego apuntará a 3. Luego procese int b = 3; Después de crear la variable de referencia de B, porque ya hay un valor de 3 en la pila, B se apunta directamente a 3. De esta manera, A y B apuntan a 3 al mismo tiempo. En este momento, si a = 4 se establece nuevamente; Luego, el compilador buscará nuevamente si hay un valor de 4 en la pila. Si no, almacene 4 y apunte a 4; Si ya existe, apunte directamente a esta dirección. Por lo tanto, el cambio en el valor A no afectará el valor b. Cabe señalar que este intercambio de datos es diferente del intercambio de referencias de dos objetos que apuntan a un objeto al mismo tiempo, porque en este caso la modificación de A no afectará B, el compilador lo hace, que es propicio para guardar espacio. Una variable de referencia del objeto modifica el estado interno de este objeto y afectará otra variable de referencia del objeto.
La cadena es un datos de embalaje especiales. Se puede usar:
Cadena str = new String ("ABC"); Cadena str = "ABC"; Hay dos formularios para crear. El primero es usar nuevo () para crear un nuevo objeto, que se almacenará en el montón. Se crea un nuevo objeto cada vez que se llama.
El segundo tipo es crear primero una variable STR al objeto de la clase de cadena en la pila, y luego averiguar si hay "ABC" almacenado en la pila. Si no, almacene "ABC" en la pila y deje que STR apunte a "ABC". Si ya hay "ABC", directamente STR apuntando a "ABC".
Al comparar si los valores en la clase son iguales, use el método igual (); Al probar si las referencias de las dos clases de envoltorio apuntan al mismo objeto, use == y use el siguiente ejemplo para ilustrar la teoría anterior.
Cadena str1 = "ABC"; Cadena str2 = "ABC"; System.out.println (str1 == str2); //verdadero
Se puede ver que Str1 y Str2 apuntan al mismo objeto.
Cadena str1 = nueva cadena ("ABC"); Cadena str2 = nueva cadena ("ABC"); System.out.println (str1 == str2); // FALSO El nuevo método es generar diferentes objetos. Generar uno a la vez.
Por lo tanto, de la segunda manera, se crean múltiples cadenas "ABC", y solo hay un objeto en la memoria. Este método de escritura es beneficioso y ahorra espacio de memoria. Al mismo tiempo, puede mejorar la velocidad de ejecución del programa hasta cierto punto, porque el JVM decidirá automáticamente si es necesario crear un nuevo objeto basado en la situación real de los datos en la pila. Para el código de cadena str = new String ("ABC");, se crean nuevos objetos en el montón independientemente de si sus valores de cadena son iguales o no, si es necesario crear nuevos objetos, aumentando así la carga en el programa.
Por otro lado, tenga en cuenta: cuando definimos una clase usando un formato como String Str = "ABC";, siempre damos por sentado que creamos un objeto STR de la clase de cadena. (No necesariamente, porque si no hay de antemano, se creará. ¡Esta es la creación del objeto. Si ya existe, entonces apunte al objeto original)! ¡El objeto puede no haber sido creado! Y tal vez solo apunte a un objeto que se ha creado anteriormente. Solo a través del método nuevo () podemos asegurarnos de que se cree un nuevo objeto cada vez. Debido a la naturaleza inmutable de la clase de cadena, cuando la variable de cadena necesita transformar con frecuencia su valor, debe considerar usar la clase StringBuffer para mejorar la eficiencia del programa.