Capire il business del software

Eric Sink ha pubblicato un articolo su MSDN in cui spiega i fondamentali di gestione di una società (che si applica anche alle società di software).
Segue poi un ragionamento su come fa un modello economico di business a funzionare, con una piccola digressione sulla difficoltà di gestione di un’azienda che si occupa di software open source (in maniera calma, pacata non ideologica e non pregiudiziale).
Vale la pena leggerlo.

Misure e dimensioni non correlate (già rettificato!)

Ieri ho messo in linea un nuovo articolo per la sezione Business Intelligence che parla di ripartizione delle misure sulle dimensioni non correlate (tipicamente nei cubi virtuali). Non ho fatto in tempo a segnalarne l’esistenza sul blog che subito ho ricevuto una segnalazione di Francesco De Chirico (che pubblicamente ringrazio) dove mi veniva suggerito il possibile uso di ValidMeasure in un’espressione MDX di esempio.
Ho già modificato l’articolo aggiungendo un paio di paragrafi alla fine che illustrano l’uso di questa funzione per semplificare leggermente la complessità dell’espressione MDX.

Memoria di Windows Task Manager

Rispondendo su un newsgroup a un messaggio dove si faceva confusione tra RAM fisica e memoria virtuale, ho pensato di scrivere anche sul blog alcune precisazioni. Forse l’argomento varrebbe un articolo, magari scrivetemi una mail per esprimere l’eventuale interesse a questo genere di argomenti.

Il Task Manager per default fa vedere una colonna che è la memoria fisica assegnata a un processo, che si chiama Working Set Size.
Tale valore non corrisponde alla memoria effettivamente richiesta e utilizzata da un processo: quel valore è disponibile in un’altra colonna che si chiama VM Size (o memoria virtuale in italiano, credo… non uso Windows in italiano).
Provo a fare un esempio per chiarire il concetto.

Ho una macchina con 512Mb di RAM e 1Gb di swap file (o file di paginazione, chiamatelo come vi pare). Nei grafici del Task Manager il picco di memoria disponibile è la somma dei due valori (quindi 1.500Mb circa).
Lancio un’applicazione che ha bisogno di 100Mb. Ne lancio un’altra che ne vuole altri 200. Vado avanti così per un po’.
E’ evidente che, avendo in tutto 1500Mb a disposizione, finirò la memoria quando raggiungerò tale limite e il grafico del Task Manager mi fa vedere proprio questo.
Ma se guardiamo la colonna con il valore “Mem Usage” (o “Utilizzo memoria” in italiano)… indovinate un po’? La somma dei valori che trovate qua è inferiore a 512Mb: tale colonna rappresenta infatti la RAM fisica assegnata al processo, che in genere è una parte della memoria virtuale richiesta dal processo. La realtà è un po’ più complessa: il Working Set Size può essere superiore alla memoria virtuale richiesta da un processo, ma tralasciamo queste condizioni un po’ particolari.
A questo punto bisogna fare una considerazione: più un processo ha un Working Set Size sufficiente a gestire tutta la memoria virtuale che ha richiesto, minore è la probabilità che debba paginare pagine di RAM su disco (in gergo si dice “swappare”). Quando non ho RAM sufficiente, il sistema operativo cerca di ripartire quella disponibile tra i processi che ne hanno bisogno, in seguito a varie condizioni (uso più recente, uso più frequente, vincoli sul Working Set per un particolare processo, ecc.).

Ora veniamo a spiegare cosa fanno i programmi che “liberano la RAM inutilmente utilizzata”, come alcuni Tweak XP: in realtà questi programmi non liberano un bel niente, ma semplicemente riducono il Working Set Size di un processo (o di tutti i processi) al fine di dare più RAM al sistema operativo, che la può usare per fare da cache del disco o (più probabilmente) per assegnarla più velocemente ad altri processi che la richiedano.
Questo serve a eseguire più velocemente un nuovo programma? Sì. Ma che effetti collaterali ha? Primo, potenzialmente aumenta la paginazione dei processi attivi non appena questi si “risvegliano” (immagina quello che ti succede quando riprendi Word con un documento aperto di 10Mb… aspetti che se lo rilegga da disco…); secondo, non libera assolutamente la memoria allocata da un processo, ma semplicemente ne sposta l’allocazione (da RAM fisica a disco virtuale, anche se messa così è una cosa molto imprecisa… ma è giusto per provare a semplificare).

La morale è che è assolutamente sbagliato usare la colonna “Mem Usage” o “Utilizzo memoria” del Task Manager per individuare i programmi che usano troppa memoria o che non rilasciano correttamente la memoria utilizzata (memory leak): tale valore non corrisponde alla memoria effettivamente richiesta dal processo, valore che si può ottenere con la colonna “VM Size” o “Dimens. mem. virtuale” sempre di Task Manager (selezione da fare nel menu “View/Select Columns” o “Visualizza/Selezione colonne”).
Ora, se non vi siete ancora annoiati, un piccolo pensiero personale.

[Mode(PoliticallyCorrect=”Off”)]
Trovo assurdo che uno sviluppatore abbia sulla sua macchina il Task Manager configurato con le colonne di default. E’ inutile usare Process Explorer se poi non si sa usare Task Manager. La colonna “VM Size” dovrebbe essere assolutamente visibile, al posto (se non avete spazio) o a fianco di “Mem Usage”. Se poi volete sapere se ci sono resource leak in un processo, aggiungete “USER Objects”, “GDI Objects” e “Handle Count”. E non volete sapere quanti thread stanno facendo qualcosa? “ThreadCount”. Infine, se volete avere un’idea se un programma sia o meno “sveglio”, è molto utile attivare “I/O Wrte Bytes”, “I/O Read Bytes” e “I/O Other Bytes”, così controllate se un processo sta facendo I/O (su disco, rete, seriale… sempre di I/O si tratta).
[Mode(PoliticallyCorrect=”On”)]

Ok, ora sto meglio.

Letture per il week-end

Il mio amico Sergio mi ha detto che, quando gli ho segnalato il sito, non ha potuto fare a meno di leggerlo tutto.
Quale? Joel on Software. Se sviluppate software per lavoro o per passione (spero entrambi) troverete un sacco di considerazioni interessanti.
Perché riprendo oggi l’argomento? Perché pochi giorni fa (il sito è una via di mezzo tra blog, articoli e pensieri a ruota libera) è comparso questo post in cui suggerisce la lettura di un libro in cui spicca la citazione: “Possiamo fare un bimbo in un mese se assumiamo 9 mamme?” – il contesto di applicazione mi pare ovvio 🙂

FrontPage 2003 e SharePoint

Oggi ho preso un po’ di tempo per provare meglio FrontPage 2003. Ho realizzato che la tanto strombazzata capacità di realizzare siti dinamici è legata al fatto di avere il sito con dietro SharePoint. Questo non significa però che sia necessario creare un sito “alla SharePoint”… voglio dire, uno fa il suo normalissimo sito e poi, in alcuni punti, “appiccica” dei dati che sono “trattati” da SharePoint (potremmo chiamarlo l’ASP.NET dei poveri?) con uno dei suoi tanti componenti.
La cosa divertente è che, nel momento in cui si iniziano a fare queste cose, si sta usando FrontPage come editor di pagine aspx… senza tutto il supporto di Visual Studio, certo, però è divertente vedere come si riesce a fare una pagina attaccata a un file XML basata su un template XSLT… senza praticamente sapere nulla della tecnologia che c’è sotto.
Messa giù in altri termini: se io faccio un sito aziendale per condividere informazioni con dei colleghi e per inserire dei dati chiedo loro di usare InfoPath (o Excel, o Word) salvando tutto in file XML… poi prendo i dati che ci sono e li pubblico sul sito Intranet in maniera completamente diversa… vabbé, è una demo che ho già visto, ma in effetti devo ammettere che non c’è bisogno di skill di programmazione per fare tutto questo. Certo, se si hanno le idee chiare su come va strutturato un documento XML è meglio. Alla fine non credo molto alla possibilità che degli “utenti” senza skill informatici riescano a fare tutto quello che vogliono da soli (comunque avrebbero bisogno di tempo, che spesso non hanno), e immagino il casino che si potrebbe venire a creare se chiunque mette dei dati in documenti XML senza alcun tipo di coordinamento… diventa un po’ come avere decine di database tutti scollegati tra loro. Però questi strumenti sono notevoli.
Dove voglio arrivare? Da nessuna parte. Sto solo dicendo che certi siti “fatti a mano” sono completamente inutili. Dal punto di vista di un’azienda che propone soluzioni, piuttosto che cercare di scrivere una soluzione proprietaria al 100% sta diventando molto conveniente pensare di formare skill elevati per sviluppare componenti (ASP.NET, Web Parts, componenti .NET in generale, e ovviamente Web Service) per integrare e personalizzare questi strumenti “generici” già fatti.

Esempi controproducenti su MSDN

Ho appena letto un documento su MSDN relativo alla chiusura di un’applicazione multi-thread con Windows Forms su .NET Compact Framework.
Non volevo credere ai miei occhi: la tecnica suggerita è quella di usare un campo bool per comunicare ai thread quando è stata richiesta l’uscita. Anche i sassi [se avessero letto il mio libro… 🙂 ] dovrebbero ormai sapere che in uno scenario simile lo strumento da usare è un’istanza ManualResetEvent: migliorano i tempi di reazione, diminuisce la necessità di fare polling a vuoto, aumenta la scalabilità….
Ok, in un’applicazione Windows Forms con due thread magari non è così importante, ma visto che il costo (in numero di linee di codice) è praticamente identico, perché non avere degli esempi che si possano applicare anche in contesti diversi? E qua il topic è proprio la comunicazione tra thread, non è un dettaglio collaterale che “per una demo” si potrebbe tollerare.
Ho già fatto i dovuti commenti sul sito MSDN, però se vi capita una situazione simile… sapete cosa *non* dovete fare 🙂

Eccezioni: il When che manca a C#

Corrado cavalli ha segnalato un interessante post di Paul Vick sull’uso del costrutto When nelle eccezioni in VB.NET. Segnalo di leggere anche i commenti al post.
Riassumendo, ecco alcune delle cose che si possono fare in VB.NET e che non si possono fare in C# (con una sintassi egualmente elegante ed efficiente):

Sub DoWork()
  Try
      ' Do some work
  Catch ex As Exception When LogException(ex)
    ' Do no work
  End Try
End Sub

Immaginando che LogException restituisca sempre FALSE, in C# diventa:

void DoWork() {
  try {
  }
  catch (Exception ex) {
    LogException( ex );
    throw;
  }
}

Vantaggio di VB: il codice è un tantino più efficiente, perché non cattura e rilancia l’eccezione ma sfrutta una sintassi IL che gestisce direttamente il concetto di filtro sull’eccezione.
Altro esempio:

Try
  ' Do some communication, e.g. send a transaction
Catch ex As CommException When ex.ErrorCode = CommError.TimeOut
  ' Re-try the transaction
End Try

Ovviamente bisogna mettere il Try/Catch all’interno di un loop per fare il retry… in C# bisogna intercettare l’eccezione e accedere alla proprietà; notare l’eleganza di VB.NET di poter accedere all’oggetto ex senza che l’eccezione sia effettivamente intercettata (lo si faceva anche nell’esempio precedente, ma qui è più chiaro).
Altro esempio pratico (sempre tratto dai commenti):

Try
  ' Do some work
Catch ex As MyAppException When Not ex.HasBeenLogged
  ' Log the exception to the event log or fire a WMI event
  Throw
End Try

Niente di nuovo, ma è interessante l’idea di avere una propria classe di eccezioni che mantiene uno stato sul fatto di essere stata scritta nel log.
Intendiamoci, non è che per queste cose passerò a VB.NET… però è giusto dire che sono funzionalità che tornerebbero comode anche in C#, anche se rispetto alla differenza di prestazioni bisogna sempre evidenziare che non deve essere così importante analizzare le prestazioni di un’eccezione generata, è molto più importante vedere le prestazioni quando non ci sono errori, le eccezioni devono essere eccezioni, non la regola.