Una fuita de memòria (en anglès, memory leak) és un tipus de fuita de recursos que es produeix quan un programa informàtic gestiona incorrectament les assignacions de memòria, de manera que la memòria que ja no és necessària no s'allibera. Una fuita de memòria pot produir-se igualment quan un objecte és emmagatzemat a la memòria però resulta inaccessible per al codi en execució, fenomen conegut com a memòria inaccessible. Com que poden esgotar progressivament la memòria del sistema mentre s'executa una aplicació, les fuites de memòria sovint constitueixen la causa, o bé un factor contribuent, de l'envelliment del programari.
Un concepte relacionat és la «fuita d'espai» (space leak), que es produeix quan un programa consumeix memòria en excés però acaba alliberant-la eventualment.
Causes Les fuites de memòria constitueixen un dels errors més freqüents en la programació, especialment en els llenguatges que no disposen de recollida d'escombraries automàtica integrada, com ara el C i el C++. En aquests casos, el programador és responsable de gestionar manualment el cicle de vida dels objectes en memòria. Habitualment, la fuita es produeix perquè la memòria assignada dinàmicament ha esdevingut inaccessible: el programa ha perdut totes les referències a un bloc de memòria, però aquest no ha estat alliberat.
En els entorns amb recollida d'escombraries automàtica, les fuites poden aparèixer quan es mantenen referències a objectes que ja no són necessaris funcionalment. Atès que el recol·lector considera que qualsevol objecte referenciable és potencialment útil, no pot alliberar-lo, fins i tot si el programa no en farà ús mai més.
Efectes Símptomes habituals Si un programa té una fuita de memòria i el seu consum creix de manera constant, normalment no es manifesta cap símptoma immediat. En els sistemes operatius moderns, la memòria que utilitza una aplicació s'allibera en el moment en què aquesta finalitza, de manera que una fuita en un programa de curta durada pot passar completament desapercebuda.
Quan un sol procés comença a consumir una quantitat creixent de memòria, ocupa progressivament una porció cada vegada més gran de la memòria principal i desplaça els altres programes cap a l'emmagatzematge secundari. La lentitud resultant i l'accés excessiu a l'emmagatzematge secundari és el que es coneix com a hiperpaginació (de l'anglès thrashing). Si el programa esgota tota la memòria disponible, qualsevol intent d'assignar-ne de nova fracassarà, i el sistema pot generar un error de segmentació o activar mecanismes específics de protecció del sistema operatiu.
Casos especialment greus La gravetat d'una fuita depèn de la durada del programa, de la freqüència d'assignació de memòria no alliberada i del context d'execució. Resulten especialment problemàtiques les fuites en programes de llarga execució, com ara els serveis en segon pla dels servidors, en els quals el consum s'acumula durant hores o dies fins a comprometre la disponibilitat del sistema. Els sistemes encastats presenten una problemàtica addicional: sovint no disposen de mecanismes automàtics d'alliberament de memòria en finalitzar els processos i poden romandre en execució durant anys sense reiniciar-se. De la mateixa manera, les fuites al nucli del sistema operatiu o al gestor de memòria poden provocar la fallada completa del sistema.
Detecció La prevalença de les fuites de memòria ha estimulat el desenvolupament d'eines de depuració especialitzades per detectar la memòria inaccessible. Entre les més populars per a programes escrits en C i C++ destaquen Valgrind, IBM Rational Purify i Dr. Memory. Les capacitats de recollida d'escombraries «conservadora» es poden incorporar com a biblioteca a qualsevol llenguatge que no les tingui integrades; un recol·lector conservador identifica i recupera la major part de la memòria inaccessible, tot i que no necessàriament la totalitat.
Prevenció Gestió automàtica de memòria La gestió de memòria automàtica és, en general, l'enfocament més robust i còmode per als desenvolupadors, atès que els allibera de la necessitat d'implementar rutines d'alliberament i de gestionar manualment l'ordre en què es realitza la neteja. La recollida d'escombraries n'és el mecanisme principal. Tanmateix, aquest enfocament pot implicar una sobrecàrrega de rendiment i no elimina la totalitat dels errors que causen fuites, especialment els que es deuen a la retenció accidental de referències.
Adquisició de recursos com a inicialització (RAII) L'adquisició de recursos com a inicialització (RAII, de l'anglès Resource Acquisition Is Initialization) és un patró de disseny habitual en C++, D i Ada. Consisteix a vincular els recursos adquirits a objectes amb àmbit definit, de manera que s'alliberen automàticament quan els objectes surten de l'àmbit d'execució. A diferència de la recollida d'escombraries, el RAII garanteix que els recursos s'alliberen en un moment determinista i conegut pel programador.
References febles Els gestors de memòria moderns ofereixen als programadors la possibilitat de marcar semànticament les referències amb diferents graus d'accessibilitat. Per evitar fuites, el desenvolupador ha de netejar les referències quan ja no les necessita, habitualment assignant-les a nul i cancel·lant el registre de qualsevol observador d'esdeveniments que mantingui una referència forta a l'objecte.
Implicacions de seguretat Els sistemes accessibles públicament, com ara els servidors web o els encaminadors, són vulnerables als atacs de denegació de servei si un atacant descobreix una seqüència d'operacions que provoca una fuita. Aquesta seqüència es denomina exploit. Les fuites al nucli del sistema operatiu comprometen igualment la seguretat global del sistema, atès que el nucli controla l'accés a tots els recursos del maquinari.
Vegeu també Recollida d'escombraries Depuració de programes Multifil
Notes
Categoria:Programació Categoria:Memòria informàtica