Conocimiento de pérdida de memoria de Java (referencia suave, referencia débil, etc.)

Sobre el autor: Socio de contenido de CSDN y experto técnico, creó una aplicación con decenas de millones de usuarios diarios desde cero.
Concéntrese en compartir series originales de artículos en diversos campos, especializados en backend de Java, desarrollo móvil, realización de negocios, inteligencia artificial, etc. Espero que me apoyen mucho.
Sin permiso, no podrá ser reproducido.

dddd

1. Introducción

Continuamos resumiendo y aprendiendo los conocimientos básicos de Java , revisando el pasado y aprendiendo lo nuevo.

2. Descripción general

Para conocer las pérdidas de memoria, necesitamos conocer algunos conocimientos básicos, como la clasificación de referencias de Java:

  • Referencia fuerte: un tipo de referencia de uso común. Esta parte de la referencia no se reciclará incluso si ocurre JVM OOM.
    Si no se utiliza un objeto de referencia fuerte, es necesario debilitarlo para que GC pueda reciclarlo, como object = null;

  • SoftReference: esta parte de la referencia se reciclará antes de que ocurra OOM (cuando la memoria jvm es insuficiente) . Si desea usar el almacenamiento en caché, puede usar LruCache en lugar de SoftReference.
    Si un objeto solo tiene referencias suaves, cuando el espacio de memoria es suficiente, el recolector de basura No se reciclará,
    si no hay suficiente espacio de memoria, se reciclará la memoria de estos objetos. Siempre que el recolector de basura no lo recopile, el programa puede utilizar el objeto.

    if(JVM内存不足) {
    
    
        // 将软引用中的对象引用置为null
        str = null;
        // 通知垃圾回收器进行回收
        System.gc();
    }
  • Referencia débil: se reciclará cuando se produzca GC .
    Una vez que se inicia gc, siempre que se encuentre un objeto con solo referencias débiles, su memoria se recuperará independientemente de si el espacio de memoria actual es suficiente .

  • Referencia fantasma: el método get devuelve nulo y no se puede obtener el valor.

Insertar descripción de la imagen aquí

3. Conocimientos relevantes

Pérdida de memoria significa que la memoria de montón asignada dinámicamente en un programa no se libera o el programa no puede liberarla por algún motivo, lo que genera un desperdicio de memoria del sistema y tiene consecuencias graves, como la desaceleración del programa o incluso un bloqueo del sistema.
Los defectos de pérdida de memoria tienen las características de ocultación y acumulación, y son más difíciles de detectar que otros errores de acceso ilegal a la memoria.

3.1 Peligros de pérdidas de memoria

  • Cuando las aplicaciones se ejecutan continuamente durante largos períodos de tiempo, el rendimiento se degrada gravemente;
  • Lanza la excepción OutOfMemoryError;
  • El programa falla automática e inexplicablemente;
  • La aplicación se quedó sin objetos vinculados.
  • etc.

3.2 Enumere los escenarios de pérdida de memoria encontrados en el desarrollo real

  • Instancias estáticas de clases internas no estáticas

  • Pérdidas de memoria causadas por singletons:
    si un objeto ya no es necesario y el objeto singleton aún contiene una referencia al objeto, el objeto no se puede reciclar normalmente, lo que resulta en una pérdida de memoria.

  • Pérdidas de memoria causadas por clases internas no estáticas que crean instancias estáticas,
    por ejemplo: Pérdidas de memoria causadas por Handler
    : Declare Handler como una clase interna no estática o una clase interna anónima en la clase, de modo que Handle contenga una referencia a la clase externa Activity de forma predeterminada.Si la Actividad está en Cuando se destruye,
    el Controlador aún tiene mensajes sin terminar o en ejecución, y el Controlador mantiene una referencia a la Actividad, lo que hace que el GC no pueda reciclar la Actividad, lo que resulta en pérdidas de memoria.

Solución: separe la clase Handler o utilice clases internas estáticas + referencias débiles para evitar pérdidas de memoria. Después de que la clase interna se cambia a estática,
los objetos o propiedades a los que hace referencia también deben ser estáticos, por lo que la clase interna estática no puede obtener referencias a objetos externos y solo puede obtener referencias de tipo estático del Área de métodos de la JVM.

Pregunta: ¿Por qué la clase interna tiene una referencia a la clase externa?

内部类虽然和外部类写在同一个文件中,但是编译后还是会生成不同的class文件,其中内部类的构造函数中会传入外部类的实例,
内部类持有外部类的对象的引用,是以“this$0”这个字段来保存的

En el lenguaje Java, las clases internas no estáticas tienen dos funciones principales:

1. 当内部类只在外部类中使用时,匿名内部类可以让外部不知道它的存在,从而减少了代码的维护工作。
2. 当内部类持有外部类时,它就可以直接使用外部类中的变量了,这样可以很方便的完成调用,
  • Pérdidas de memoria causadas por subprocesos.
    Pérdidas de memoria causadas por ThreadLocal. ThreadLocal hará una copia de la variable.

Solución: separe las clases AsyncTask y Runnable o utilice clases internas estáticas para evitar pérdidas de memoria.

Clases internas anónimas/clases internas no estáticas y subprocesos asíncronos.

  • Pérdidas de memoria causadas por recursos no cerrados.
    Para recursos como BroadcastReceiver, ContentObserver, File, Cursor, Stream, Bitmap, etc., deben cerrarse o cerrarse a tiempo cuando se destruye la Actividad; de lo contrario, estos recursos no se reciclarán, lo que provocará pérdidas de memoria. El objeto de recurso no está cerrado: cursor, archivo

  • Las variables estáticas de las clases contienen grandes objetos de datos (campos estáticos)

  • Pérdidas de memoria causadas por objetos en contenedores de recolección que no se limpian

  • Cuando finalize()
    anula el método finalize(), los objetos de esta clase no serán recolectados inmediatamente por el recolector de basura. Si hay un problema con el código del método finalize(), potencialmente puede causar OOM;

  • El objeto registrado no se destruye: transmisión, escucha de devolución de llamada

  • WebView: use un proceso separado

3.3 La diferencia entre referencia suave y referencia débil

  • Los objetos débilmente referenciados tienen un ciclo de vida más corto
  • El momento del reciclaje es diferente.

4. Lectura recomendada

columna java

Columna SQL

Estructuras de datos y algoritmos

columna de aprendizaje de Android

Sin permiso, no podrá ser reproducido.

Insertar descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/fumeidonga/article/details/132214403
Recomendado
Clasificación