JavaRush /Blog Java /Random-ES /Pausa para el café #94. Revisión de cinco analizadores de...

Pausa para el café #94. Revisión de cinco analizadores de código Java estático. Errores de memoria de pila y montón de Java

Publicado en el grupo Random-ES

Revisión de cinco analizadores de código Java estático

Fuente: DZone Los desarrolladores suelen necesitar varios programas, incluidos analizadores de código estático, que puedan encontrar y corregir códigos erróneos en las primeras etapas del desarrollo. Si bien las revisiones de código son una herramienta invaluable en este esfuerzo, a veces la cantidad de revisores de código que tienen que revisar y revisar es abrumadora. Esto requiere mucho tiempo y esfuerzo. Esto también lleva al hecho de que los revisores a menudo prestan atención sólo a los fragmentos de código que son críticos para el funcionamiento del programa. Mientras que las herramientas de análisis estático verifican todo el código con la misma precisión. Pausa para el café #94.  Revisión de cinco analizadores de código Java estático.  Errores de memoria de pila y montón de Java - 1He reunido varios analizadores de código que son compatibles con IntelliJ IDEA. Espero que esto te ayude en tu trabajo.

Analizador IntelliJ IDEA incorporado

El analizador de código Java estático integrado en IntelliJ IDEA no es de ninguna manera inferior a las herramientas de análisis estático especializadas. La búsqueda de fragmentos de código sospechosos, desordenados o incorrectos se lleva a cabo mediante varios métodos de análisis estático: análisis de flujo de datos y coincidencia de patrones. IntelliJ IDEA tiene una gran cantidad de inspecciones. En verdad, muchos de ellos no siempre informan con precisión del error. Más bien, indican descuido en el código o la posibilidad de cambiarlo con una buena alternativa. Después de estudiar un poco “Inspecciones → Java”, noté una cosa. Es más probable que las inspecciones en las categorías de errores probables, problemas numéricos y problemas de serialización encuentren errores reales. En cualquier caso, debes realizar las pruebas tú mismo y determinar cuáles serán útiles para tu proyecto. Debido a que el análisis estático se realiza en modo de edición de código, en IntelliJ IDEA puede corregir errores a los pocos segundos de que ocurran. El editor resalta inmediatamente el fragmento de código incorrecto. Pausa para el café #94.  Revisión de cinco analizadores de código Java estático.  Errores de memoria de pila y montón de Java - 2¡Es realmente conveniente y genial! Además, si utiliza la combinación “Alt + Enter” en un fragmento de código seleccionado, puede seleccionar una de las opciones para corregir el error a través del menú contextual: También puede averiguar el motivo para ejecutar una inspección en particular Pausa para el café #94.  Revisión de cinco analizadores de código Java estático.  Errores de memoria de pila y montón de Java - 3. En algunos casos, esto reduce el tiempo de búsqueda: Pausa para el café #94.  Revisión de cinco analizadores de código Java estático.  Errores de memoria de pila y montón de Java - 4puede ejecutar el análisis manualmente seleccionando “Analizar → Verificar código”. O puede ejecutar una verificación individual usando “Analizar → Ejecutar verificación por nombre”. Antes de hacer esto, especifique el alcance del análisis (para un proyecto, módulo o archivo individual). Cuando ejecuta un análisis de esta manera, algunas inspecciones quedan disponibles y no funcionan en modo de edición debido a su complejidad. Después del análisis, los resultados se agruparán por categoría/directorio en una ventana separada. Desde esta ventana puede navegar a un activador de validación específico: Pausa para el café #94.  Revisión de cinco analizadores de código Java estático.  Errores de memoria de pila y montón de Java - 5IntelliJ solo le permite guardar el resultado del análisis en formatos HTML y XML. Desafortunadamente, en mi opinión, lo más conveniente es trabajar con los problemas detectados en el propio IDE. Nota. La mayoría de las funciones del analizador estático están disponibles en la edición comunitaria gratuita IntelliJ IDEA.

SonarJava

SonarJava es un analizador de código estático para Java de SonarSource. La lista de sus funciones incluye:
  • Más de 150 reglas de detección de errores;
  • Más de 350 reglas para reconocer olores de códigos;
  • Más de 40 reglas para detectar vulnerabilidades potenciales ;
  • Integración con Maven, Gradle, Ant, Eclipse, IntelliJ IDEA, VS Code;
  • Ampliable con reglas de diagnóstico personalizadas;
  • Herramienta SAST especializada: la mayoría de las reglas de diagnóstico se compilan de acuerdo con CWE , CERT , OWASP .
Puede ejecutar el análisis tanto en varios IDE (a través del complemento SonarLint ) como por separado en SonarQube . SonarLint puede trabajar en paralelo con el analizador de código IntelliJ IDEA integrado. Si pasa el cursor sobre un fragmento de código resaltado, a menudo podrá ver advertencias de ambos analizadores: Pausa para el café #94.  Revisión de cinco analizadores de código Java estático.  Errores de memoria de pila y montón de Java - 6Por supuesto, puede ver la advertencia en una ventana separada: Pausa para el café #94.  Revisión de cinco analizadores de código Java estático.  Errores de memoria de pila y montón de Java - 7En general, la capacidad de ejecutar SonarJava de diferentes maneras lo hace atractivo. Esto les da a los desarrolladores la libertad de elegir una herramienta al escribir código.

Buscar errores/Detectar errores

Desafortunadamente, FindBugs no se ha actualizado durante mucho tiempo; la última versión estable se lanzó en 2015. Pero aún lo recordamos y usamos, ya que es quizás el analizador de código Java estático gratuito más famoso. Si le pregunta a un desarrollador de Java sobre el análisis estático, probablemente pensará inmediatamente en FindBugs. El analizador de código abierto SpotBugs se convirtió en una continuación lógica del abandonado FindBugs. Tiene todas las ventajas y desventajas de FindBugs. El tiempo dirá si esto es bueno o malo. Mientras tanto, la comunidad de analizadores lo está desarrollando activamente. Características clave de SpotBugs:
  • Más de 400 reglas de detección de errores;
  • Integración en Ant, Maven, Gradle, Eclipse, IntelliJ IDEA;
  • Ampliable con reglas de diagnóstico personalizadas.
Para encontrar código sospechoso se utilizan las mismas metodologías: coincidencia de patrones y análisis de flujo de datos. El analizador detecta varios tipos de errores relacionados con subprocesos múltiples, rendimiento, vulnerabilidades, ofuscación de código, etc. En IntelliJ IDEA, la ventana de alerta tiene este aspecto: Pausa para el café #94.  Revisión de cinco analizadores de código Java estático.  Errores de memoria de pila y montón de Java - 8Las alertas se pueden agrupar por categoría, clase, directorio y nivel de confianza. Puede ver simultáneamente alertas y documentación para cualquier regla de diagnóstico. El análisis se inicia manualmente. Después del análisis, todos los fragmentos de código problemáticos se resaltan junto con otras advertencias de IntelliJ IDEA y SonarLint. Sin embargo, hay un problema. Debe volver a ejecutar el análisis para actualizar las advertencias y reflejar los cambios realizados en el archivo. También hay muchas advertencias, por lo que el analizador debe configurarse antes de su uso activo.

Estudio PVS

PVS-Studio se basa en la biblioteca de código abierto Spoon. Toma el código fuente como entrada y construye un modelo AST bien diseñado con información semántica. Basado en este modelo, el analizador utiliza técnicas modernas como:
  • Análisis de flujo de datos;
  • Actuación simbólica;
  • Anotaciones de métodos;
  • Análisis basado en patrones.
Actualmente, el analizador utiliza más de 105 reglas de diagnóstico que identifican varios fallos del código. Estos incluyen correcciones de errores tipográficos, cambio de nombre de referencias nulas, código inalcanzable, índice de matriz fuera de límites, violación del uso del contrato de método y otros errores. Puede conocer todas las capacidades de las reglas de diagnóstico aquí . Funciones principales de PVS-Studio:
  • El analizador se centra en encontrar errores reales;
  • Además de la versión CLI, también existe integración con IntelliJ IDEA, Maven, Gradle, Jenkins, SonarQube;
  • Capacidad para ejecutar el analizador en modo incremental;
  • El analizador identifica posibles problemas de compatibilidad con la API de Java SE al migrar un proyecto de Java 8 a versiones más recientes;
  • PVS-Studio convierte el informe a varios formatos fáciles de usar: JSON, XML, HTML, TXT;
  • Herramienta SAST especializada: la mayoría de las reglas de diagnóstico se compilan de acuerdo con CWE , CERT , OWASP .

PMD

PMD es un analizador estático de código abierto. Identifica errores comunes de desarrollo: variables no utilizadas, bloques vacíos, creación de objetos innecesarios y otros problemas. El analizador utiliza el código fuente como entrada. Actualmente, PMD analiza un archivo fuente por proceso, lo que impone limitaciones a la integridad del análisis. Los autores del PMD aconsejan montar el proyecto antes del análisis. Esto le permite extraer información sobre los tipos utilizados en el código que se analiza. Funciones principales del PMD:
  • Integración con varios IDE (IntelliJ IDEA, Eclipse, NetBeans) y sistemas de compilación (Maven, Gradle, Ant);
  • Admite varios formatos de informes del analizador: SARIF, CSV, IDEA, JSON, texto (predeterminado), XML, HTML, TextColor, etc.
  • Tiene más de 300 plantillas de reglas de diagnóstico. Categorías: estilo de codificación, mejores prácticas, errores, subprocesos múltiples, rendimiento, etc.
  • Proporciona un CPD (Detector de copiar y pegar) junto con un PMD que detecta duplicados en el código.
Si observamos todas las reglas de diagnóstico, PMD se centra más en resolver problemas de estilo de codificación y detectar errores obvios. Las reglas de diagnóstico pueden entrar en conflicto entre sí, por lo que deben configurarse antes de utilizar el analizador. También puede ejecutar el análisis a través de un complemento para IntelliJ IDEA, pero no puede seleccionar archivos individuales para el análisis. La ventana de advertencia se ve así: Pausa para el café #94.  Revisión de cinco analizadores de código Java estático.  Errores de memoria de pila y montón de Java - 9En mi opinión, trabajar con advertencias no es muy conveniente, ya que no se pueden agrupar por archivos y mensajes no obvios. Solo aparecen cuando pasas el cursor sobre la advertencia.

Conclusión

Por supuesto, además de los analizadores comentados anteriormente, existen otras soluciones. Hay programas tanto pagos (Coverity, Klockwork, JArchitect) como gratuitos (Error Prone, Infer, Checkstyle). Todos se centran en una cosa: evitar que código incorrecto o potencialmente defectuoso llegue a producción. No tengo derecho a juzgar qué analizador es más adecuado para esta tarea. Pero los analizadores que desarrollan análisis de flujo de datos y ejecución simbólica tienen más probabilidades de encontrar un error real en el código. Si elige un analizador estático, preste atención a:
  • integración en varios IDE;
  • integración en sistemas de montaje;
  • facilidad para iniciar el analizador en el servidor;
  • la capacidad de detectar errores en el modo de edición de código;
  • la capacidad de trabajar cómodamente con advertencias;
  • orientación SAST;
  • porcentaje de falsos positivos;
  • Complejidad de la configuración.
  • La combinación de todos los pros y los contras le llevará a determinar la cantidad de analizadores estáticos que considere mejores.
Nota: Proporcioné ejemplos de integración en IntelliJ IDEA, ya que lo uso con frecuencia.

Errores de memoria de pila y montón de Java

Fuente: DZone Ahora veremos los principales errores que pueden ocurrir en la memoria de pila o montón de Java, pero primero recordemos qué significan estos dos términos.
  • La memoria dinámica es un área especial de memoria en la que se almacenan los objetos Java.
  • La memoria de pila es un área de memoria temporal para almacenar variables al llamar a un método.
La principal excepción que describe un problema de memoria dinámica es java.lang.OutOfMemoryError . Pausa para el café #94.  Revisión de cinco analizadores de código Java estático.  Errores de memoria de pila y montón de Java - 10

Espacio de montón de Java

Este error ocurre cuando un programa Java no logra asignar un nuevo objeto en un área de memoria dinámica.

Límite de gastos generales del GC excedido

Un programa Java dedica demasiado tiempo a la recolección de basura. Este error aparece cuando la recolección de basura ocupa el 98% del tiempo del programa y recupera menos del 2% del espacio de memoria.
public class OutOfMemoryErrorDemo {
    public static void main(String[] args) {
        int i = 0;
        List<String> stringList = new ArrayList<>();
        while (i < Integer.MAX_VALUE) {
            i++;
            String generatedString = new String( "Some string generated to show out of memory error example " + i);
            stringList.add(generatedString);
        }
    }
}
Aquí stringList contiene una referencia a nuestras cadenas generadas, por lo que el recolector de basura no puede eliminar las cadenas generadas de la memoria, pero intenta eliminar cualquier otra basura en la aplicación. Pero esto no es suficiente.

El tamaño de matriz solicitado excede el límite de VM

El error ocurre cuando intentas asignar una matriz cuando no hay suficiente espacio en el montón.
public class OutOfMemoryErrorDemo {
    public static void main(String[] args) {
        // we try to create too long array
        long[] array = new long[Integer.MAX_VALUE];
    }
}

metaespacio

Se genera una excepción con este mensaje cuando no hay espacio en la región del metaespacio para información de datos de clase.

No hay espacio de intercambio (Solicite bytes de tamaño por motivo. ¿Sin espacio de intercambio?)

El error aparece cuando no se pudo asignar memoria en el montón nativo o su tamaño es insuficiente.

motivo stack_trace_with_native_method

Una interfaz Java nativa o un método nativo no pudieron asignar memoria en el montón. StackOverFlowError : cuando hay demasiadas llamadas a métodos. Por lo general, un método que tiene recursividad genera una excepción.
public class StackOverFlowErrorDemo {

    public static void main(String[] args) {
        recursiveMethod(2);
    }

    public static int recursiveMethod(int i) {
      	// it will never stop and it allocates all stack memory
        return recursiveMethod(i);
    }
}
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION