Categorie
Blog Programmazione tricks

Come si verificano I memory leak in Java

Come si verificano I memory leak in Java

Qualche giorno fa ho letto un articolo molto interessante: “How Memory Leaks Happen in a Java Application”.

Uno dei vantaggi del linguaggio Java è quello di gestire la deallocazione degli oggetti in maniera automatica attraverso il “garage collector”. In particolari circostanze questa gestione può fallire e possono verificarsi dei memory leak.

In informatica, un memory leak (“perdita o fuoriuscita di memoria”) è un particolare tipo di consumo non voluto di memoria dovuto alla mancata deallocazione dalla stessa, di variabili/dati non più utilizzati da parte dei processi. (Wikipedia)

I memory leak non dipendono da una errata implementazione del garbage collector,  ma da un uso improprio degli oggetti costruiti dall’applicazione. È un classico problema di PEBCAK (Problem Exists Between Chair And Keyboard), ed è tra i più difficili da diagnosticare.

Categorie
Programmazione TDD

Test Driven Development – Primi passi

Eccoci al secondo articolo sul TDD. Spero di avervi incuriosito nell’introduzione precedente. É arrivata l’ora di passare agli aspetti pratici.

Premessa

La tecnica del TDD è applicabile con diversi linguaggi, tecnologie e Framework. In questa serie di articoli useremo principalmente il linguaggio di programmazione JAVA. Vedremo l’utilizzo del TDD con diversi Framework e paradigmi di programmazione (orientata agli oggetti, orientata agli aspetti).

Prerequisiti per la prima lezione

Conoscenza dei fondamenti di programmazione a oggetti.

Superficiale conoscenza del linguaggio di programmazione JAVA (versione 7).

Test Driven Development

Ciclo di sviluppo

Nel primo articolo, abbiamo indicato qual è il ciclo di sviluppo utilizzando la tecnica del TDD:

Ciclo sviluppo TDD
Ciclo sviluppo TDD
Categorie
Programmazione TDD

Test Driven Development – Introduzione

 

Red Pill TDD

Questo articolo, sarà il primo di una lunga serie sul Test Driven Development (Sviluppo Guidato dai Test) o TDD.

Il processo di sviluppo TDD ha fatto il suo debutto circa 18 anni fa come parte integrante dell’Extreme Programming (XP) ed è ora adottato da tutti i team di sviluppo che fanno uso di metodi agili, e non solo. Io ne ho sentito parlare non più di 10 anni fa ed ero molto scettico al riguardo. All’inizio facevo delle prove per conto mio, mai in applicazioni che avrei dovuto sviluppare per lavoro. Prima il mio approccio era: analisi su carta, sviluppo, test completo, debug, correzione, test, analisi, debug, sbattimento di testa, debug, correzione, sviluppo, … e così via. Producendo software per soldi (ovvero per lavoro), non pensavo ci fosse tempo per scrivere degli Unit Test o, addirittura, partire dal test!

Adesso non rilascio una classe se prima non ci sono degli Unit Test che la coprono (torneremo in seguito sul Code Coverage) e, addirittura, non scrivo codice se prima non c’è un test che fallisce.

Ok per i test, ma non scrivere codice se non c’è un test che fallisce? Ma che significa?

Categorie
Programmazione

Java 8 – Parte 2 – Sintassi delle espressioni lambda

Nell’articolo precedente abbiamo visto una piccola introduzione all’utilizzo delle espressioni lambda in Java 8. Prima di saltare la tana del bianconiglio e addentrarci  nel paradigma funzionale in Java 8, vediamo come è possibile scrivere un’espressione lambda.

Di seguito verranno presentati 6 diversi modi.

Categorie
Programmazione

Java 8 – Parte 1 – Perché abbiamo bisogno del Lambda calcolo in Java?

Questo è il primo di una serie di articoli su Java 8. In questa serie di articoli analizzeremo alcune nuove caratteristiche del linguaggio e come utilizzarle al meglio.

Per un programmatore che ha esperienza con Java, sarà ormai chiaro che Java si sta avvicinando al paradigma funzionale. L’elevata espressività di un paradigma funzionale ci consentirà di migliorare il nostro codice  e soprattutto approcciare in maniera differente alcune problematiche.

Espressioni Lambda – λ-calcolo

Esempio confronto con lambda calcolo in Java

Categorie
Programmazione

Pro e contro se ritornare uno Stream o un Collection

Molte Java API hanno metodi che ritornano un Collection (eviterò di scrivere una Collection). Dalla versione 8 di Java è possibile restituire anche uno Stream. Dato che uno Stream è più flessibile ed efficiente in moti casi, le API che andremo a sviluppare dovrebbero restituire uno Stream o un Collection?

Un esempio significativo

Per restituire un Collection, gli elementi della collezione devono essere prima di tutto creati e poi caricati in memoria. Così ci sono due costi: computazionale e allocazione di memoria.

Categorie
Programmazione

Passaggio di parametri in JAVA

Una domanda che mi fanno molti o che mi capita di leggere spesso riguardo JAVA e’: “come faccio a passare dei parametri per riferimento?”. La mia risposta e’: “NON SI PUO’!!”.

Ecco un mito da sfatare:

“Gli oggetti sono passati per riferimento, i primitivi per valore” FALSO

In JAVA ogni cosa è passata per valore. Gli oggetti, non vengono passati affatto.
I valori delle variabili sono sempre o primitive o riferimenti, mai oggetti!

Prima di tutto, definiamo cosa significa “passaggio per riferimento”. Una delle definizioni che preferisco e’ quella di Dale King scritta nel ng comp.lang.java.help: “The lvalue of the formal parameter is set to the lvalue of the actual parameter”. Quindi se ad esempio scriviamo questo codice:

Categorie
Programmazione

Java Native Access (Parte 2) – Primi passi

Per comprendere l’utilizzo di una tecnologia non c’è nulla di meglio che provarla. Quale migliore esempio se non il classico Hello, World!”?

Il codice che analizzeremo tra breve è preso direttamente dagli esempi presenti nella guida ufficiale.

HelloWorld.java

package it.spicydev.blog.jna;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

/**
 * Date: 1/21/12 7:06 PM
 *
 * @author Mircha Emanuel `ryuujin` D'Angelo
 * @version 1.0
 */
public class HelloWorld {
     /**
     * Java interface to hold the native library methods extending the Library interface
     */
    public interface CLibrary extends Library {
        CLibrary INSTANCE = (CLibrary) Native.loadLibrary(
                (Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);

        void printf(String format, Object... args);
    }

     public static void main(String[] args) {
        CLibrary.INSTANCE.printf("Hello, World\n");
        CLibrary.INSTANCE.printf("%d %f\n",1,3.14);
    }

}
Categorie
Programmazione

Java Native Access (parte 1) – Introduzione

Se è necessario accedere a delle funzionalità offerte da librerie native compilate per il sitema su cui girerà il nostro programma (host), si utlizzano le JNI. Attraverso di esse è possibile scrivere una nostra libreria in codice nativo (C, C++) che fa da ponte tra la nostra class Java e i metodi della libreria nativa che intendiamo utilizzare.

Con la libreria Java Native Access (JNA) non è più necessario. Essa ci consente di accedere alle risorse di una libreria dinamica (ovvero shared) scrivendo solo codice Java.

Per chi conosce Python, avrà sentito parlare di CTypes che realizza qualcosa di molto simile. Vi consiglio anche di dare un’occhiata a SWIG, ma adesso concentriamoci su JNA.

JNA permette di accedere solo alle risorse di librerie shared o dinamiche (.so in Linux, .dll in windows). Il perché non è possibile utilizzare librerie statiche (.a o .lib) è chiaro se si tiene conto del fatto che sono una sorta di archivio che deve essere staticamente linkato nell’eseguibile. Dato che non è possibile caricare una libreria statica a runtime, è chiaro che non è possibile utilizzare le JNA per servirsene.

Le risorse di una libreria nativa vanno mappate all’interno della classe Java tenendo conto di una relazione di equivalenza tra i tipi. Attraverso

Categorie
Programmazione

Class Adapter – Design Pattern Strutturale

Lo scopo del pattern Adapter è convertire l’interfaccia di una classe in un’altra interfaccia che i client si aspettano.

E’ definito anche Wrapper e rientra nella categoria dei pattern strutturali.

Penso non sia raro ritrovarsi con tante belle classi di libreria e non poterle usare perche’ incompatibili con l’interfaccia richiesta. Ecco che interviene l’adapter.

L’adapter va usato quando subentrano queste motivazioni:

  • una classe di una libreria non puo’ essere usata perche’ incompatibile con l’interfaccia richiesta dalla nostra applicazione
  • non e’ possibile (o non conveniente) cambiare l’interfaccia della libreria
  • non e’ possibile (o non conveniente) cambiare l’applicazione.

I partecipanti in questo Design Pattern sono: