Onko pythonissa tapaa vapauttaa muistia kun ei muuttujaa enää tarvita ?
Olion (objektin) varaama muisti vapautuu automaattisesti heti, kun kyseiseen olioon ei enää ole viittauksia. Esimerkiksi:
1. Luodaan lista (eli taulukko), jossa on kolme lukua. Viitataan taulukkoon muuttujalla
a:
a = [1, 2, 3]
2. Luodaan toinen lista ja vaihdetaan muuttuja
a viittaamaan siihen:
a = [4]
Tässä viittaus alkuperäiseen listaolioon [1, 2, 3] häviää, ja Python vapauttaa olion muistista.
Ongelmia syntyy syklisistä viittauksista, eli jos esimerkin alkuperäisessä listassa olisi ollut viittaus listaan itseensä:
a = [1, 2, 3]
a.append[a] # Tässä lisätään listan perään viittaus listaan itseensä
a = [4]
Nyt varsinainen viittaus listaan [1, 2, 3, [...]] poistetaan, mutta sen sisälle jää syklinen viittaus, eikä pelkkä reference counting tunnista, että olio pitäisi poistaa muistista. Sen sijaan Pythonin roskienkerääjä (garbage collector) osaa poistaa tällaiset tapaukset. Roskienkeruu suoritetaan ajoittain, eli ylimääräistä muistia voi jäädä varatuksi joksikin aikaa. Jos ohjelma käsittelee suuria datamääriä, tästä voi aiheutua oikeastikin ongelmia. Silloin voi olla tarpeen pyytää välitöntä roskienkeruuta kutsumalla gc.collect()-funktiota.
Käytännössä verkkotietorakenteita lukuun ottamatta sykliset viittaukset ovat harvinaisia, ja Python vapauttaa muistin automaattisesti heti kun viittaukset poistetaan.
Katso myös:
https://stackoverflow.com/questions/34146304/why-should-you-manually-run-a-garbage-collection-in-pythonhttps://docs.python.org/3/library/gc.htmlToinen kysymys...
Voiko pythonissa parametrina funktiolle antaa pelkän osoittimen tai viitteen datasta ?
Python käyttää "pass by assignment"-tyyppistä funktion parametrien välitystä. Käytännössä se tarkoittaa, että funktion parametreihin sijoitetaan funktiokutsussa annetut arvot. Se johtaa siihen, että funktion suorituksen alussa parametrit ovat viittauksia samoihin olioihin, jotka funktiolle on annettu kutsuttaessa. Esimerkiksi:
def appendzero(l):
l.append(0)
a = [1,2,3]
appendzero(a)
print(a)
[1, 2, 3, 0]
Perustyypit kuten kokonais- ja liukuluvut ja merkkijonot ovat kuitenkin immutable-olioita, jolloin funktio ei voi vaikuttaa niiden sisältöön siten, että muutos näkyisi funktion ulkopuolella. Ylläolevan esimerkin taulukko sen sijaan on mutable, ja siksi siihen lisätty uusi alkio näkyy pääohjelman puolella. Myös taulukossa ennestään olevat alkiot voi korvata uusilla, vaikka ne sinänsä ovat immutable-tyyppisiä. Taulukossa vain vaihdetaan viittaukset uusiin olioihin ja vanhat lukuarvot vapautuvat muistista, koska niihin ei enää viitata.
Katso myös:
https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-referencehttps://medium.com/school-of-code/passing-by-assignment-in-python-7c829a2df10ahttps://realpython.com/python-pass-by-reference/Käytännön ongelmana itselläni on, että lataan koneelle 1 Gt:n CSV-tiedoston, jota käsittelen pythonilla s.e. se kuluttaa ihan perusosassakin jopa 10 Gt, joten sen käyttämää kulutusta pitäisi pystyä pienentämään.
Kuulostaa siltä, että koodi lataa tiedoston sisällön kokonaisuudessaan muistiin ja tekee siitä mahdollisesti useampia kopioita käsittelyn aikana.
Kannattaa tosiaan pohtia, miten ohjelma täsmälleen käsittelee muistiin ladattua dataa, ja tarvitaanko se kokonaisuudessaan. Ratkaistavasta ongelmasta riippuen voi olla mahdollista iteroida CSV-tiedostoa rivi kerrallaan tallentamatta koko sisältöä muistiin. Esimerkiksi keskiarvot ja maksimit ja minimit voi laskea hyvin pienellä muistinkäytöllä.
Voidaan katsoa ongelmallista koodia tarkemminkin, jos pystyt näyttämään sen.