Mitä tapahtuu jos unohdan vapauttaa allocatun muistin?
free() alloc()
15
1359
Vastaukset
- Anonyymi
Käyttiksen pitäisi osata vapauttaa muisti, kun ohjelman suoritus loppuu. Lähinnä se free():n käyttö liittyy hyvään ohjelmointitapaan, jottei muistia ala fragmentoitumaan pitkään käynnissä olevien ohjelmien ajon aikana. Tarpeettomiksi käyvät allokoinnit kannattaa siis opetella vapauttamaan jo ohjelman suorittamisen aikana.
- Anonyymi
Ei mitään tärkeää.
- Anonyymi
Jaa..a, jos vaikka kokeilisit? Oma kokemukseni on, että järjestelmä voi jopa kaatua - sellaista ei vaan tapahdu, että muisti loppuu. Parhaassa tapauksessa prosessi heittää core-tiedoston levylle ja kaatuu - pahimmassa joutuu painamaan reset-nappia, koska joku järjestelmäprosessi on onnistunut skeduloimaan itsensä juuri pahimmalla hetkellä ja on ajossa kriittisessä kohdassa jossa tarvitaan kalloc. Pitäisiköhän muistin varauksen olla vielä kernel-space:ssa, jotta sen saisi loppumaan myös kerneliltä?
Parhaimmillaan siis voi toipuakin tuosta, koska tilaa usein varataan 4k sivu kerrallaan ja silloin on aika hyvät todennäköisyydet, että sitä on vielä jäljellä.- Anonyymi
Ehkä muinoin historiassa noin tapahtui.
- Anonyymi
Anonyymi kirjoitti:
Ehkä muinoin historiassa noin tapahtui.
No, jos historiaa on tiktokin katsominen selaimella viime joulukuussa, niin ehkä sitten. Siellä jäi kaikki videot firefoxiin ja lopulta muisti loppui. Itse asiassa, en osaa sanoa mitä lopulta olisi tapahtunut, koska puolen minuutin päästä kiintolevyn swapattua kuumeisesti ja jumitettua koneen täydellisesti painoin resettia.
- Anonyymi
Anonyymi kirjoitti:
No, jos historiaa on tiktokin katsominen selaimella viime joulukuussa, niin ehkä sitten. Siellä jäi kaikki videot firefoxiin ja lopulta muisti loppui. Itse asiassa, en osaa sanoa mitä lopulta olisi tapahtunut, koska puolen minuutin päästä kiintolevyn swapattua kuumeisesti ja jumitettua koneen täydellisesti painoin resettia.
"jäi kaikki videot firefoxiin" Mitähän tuokin tarkoittaa.
- Anonyymi
Anonyymi kirjoitti:
"jäi kaikki videot firefoxiin" Mitähän tuokin tarkoittaa.
" 'jäi kaikki videot firefoxiin' - Mitähän tuokin tarkoittaa."
Ilmeisesti sitä, että ko. käyttäjä on Firefoxissa aina avannut uuden välilehden tai ikkunan kun on halunnut katsoa uuden videon, ja kaikki videoita sisältävät sivut ovat yhtäaikaa auki selaimessa.
Ja yleensä tuosta seuraa, se, että selaimilta loppuu muisti, kun selainten muistinhallinta on (M-Karin päinvastaiststa väitteistä huolimatta) huonosti tehty.
Ja kun selaimelta loppuu muisti, niin selain yleensä lakkaa reagoimasta näppäimistöltä ja/tai hiirellä annettuihin komentoihin, jolloin selaimelle ei voi tehdä muuta kuin (esim. Firefoxin tapauksessa) Windowsin tehtävänhallinnalla tappaa kaikki prosessit, joiden nimi on "firefox.exe".
Vinkki: JOS ja KUN joudut noin tekemään, kannattaa aloittaa se prosessien tappaminen siitä firefox.exe -prosessista, joka kuluttaa eniten RAM -muistia. Kun pahimman muistisyöpön tappaa ensin, myös muu windowsin toiminta (joka ei suoraan liity firefoxiin mitenkään) nopeutuu kummasti.
Olen ohjelmointipalstalla yrittänyt kysyä neuvoa, miten saisi firefoxin itse käännettyä lähdekoodista EXE -tiedostoksi, mutta ikävä kyllä tulee vain ns. v*ttuiluvastuksia.
Kas kun jos sen voisi itse kääntää, EHKÄ sille huonolle muistinhallinnallekin saisi jotakin tehtyä.
Minkähänlaisella C:n esiprosessorin (eli siis tekstipohjaisten makrojen) käytöllä saisi väännettyä asian niin, että jokainen osoitin korvataan virtuaaliosoittimella ?
siis jos koodissa on vaikkapa:
int *ptr_i;
int k;
niin kun koodissa lukee vaikkapa:
k = *ptr_i;
alunperinhän tuo lukee osoittimen ptr_i osoittamasta paikasta kokonaisluvun ja kopioi sen muuttujaan k.
Muutoksen jälkeen homman pitäisi toimia niin, että ptr_i ei ole enää absoluuttinen muistiosoite, vaan relatiivinen muistiosoite, joka on suhteellinen vaikkapa MEM_BASE -osoittimeen.
siis näin:
void* MEM_BASE;
Ja jos alunperin ptr_i on osoittanut johonkin muistipaikkaan suoraan, niin muutoksen jälkeen, jos tuo jokin muistipaikka on vaikkapa 8 tavua myöhemmin kuin MEM_BASE:n osoittama paikka, niin silloin (unsigned int)ptr_i == 8.
Ja sopivan tekstimakron avulla pitäisi saada homma toimimaan niin, että kun alkuperäisessä koodissa lukee k = *ptr_i; niin uusittuna vaikkapa:
k = *RELMEM(ptr_i);
Jossa tuo RELMEM -makro siis ottaa osoittimen MEM_BASE, lisää siihen ptr_i:n arvon, ja palauttaa summan void* -tyyppisenä.
Tuon lisäksi toki pitäisi saada aikaiseksi se, että kun ohjelma alunperin asettaa jonkin osoitteen tuohon ptr_i -osoittimeen, niin muutoksen jälkeen sen pitäisi asettaa ptr_i -muuttujaan tieto, montako tavua myöhemmin tuo haluttu osoite on verrattuna tuohon osoittimeen MEM_BASE.
Miksikö?
No koska tuolla tavalla voisi hoitaa homman niin, että tuon MEM_BASE:n arvoa voi halutessaan muuttaa, ja jopa niin, että kun MEM_BASE=NULL, niin silloin tiedetään, ettei mikään siihen relatiivinen osoitin ole sillä hetkellä käyettävissä suoraan, vaan ensin pitää palauttaa RAM -muistin sisältö väliaikaistiedostosta kiintolevyltä.
Tuohon kun saisi jotenkin ohjelmoitua sellaisen funktion, jota kutsutaan, jos tuo RELMEM -makro huomaa, että taustalla käytettävä MEM_BASE=NULL, ja vasta tun lisäfunktion suorituksen jälkeen muistiosoitus voi toteutua.
Tuo lisäfunktio siis lataa uudelleen RAMiin väliaikaistiedostosta kiintolevyltä sellaisen sisällön, joka on RAMista aiemmin poistettu.
Ideana siis, että vain yhden web -sivun sisältö kerrallaan on RAM -muistissa, ja jos on auki useita ikkunoita ja/tai välilehtiä, niin vain sen aktiivisen välilehden sisältö on RAM -muistissa, kaikkien muiden ikkunoiden ja/tai välilehtien sisältö on väliaikaistiedostosta kiintolevyllä.
Tuolla tekniikalla ihan sama vaikka avaisit 10 miljoonaa web -sivua samanaikaisesti, niin siltikin vain 1 web -sivun materiaali on kerrallaan RAM -muistissa, ja kun klikkaat eri välilehteä tai alt-TABin avulla menet eri selainikkunaan, niin äsken esillä ollut web -sivu laitetaan väliaikaistiedostoon kiintolevylle, ja uuden (klikatun tai ALT-TABitetun) web -sivun sivun sisältö ladataan RAMiin.
Näin minä haluaisin selaimen toimivan, koska silloin selain ei milloinkaan voi kaatua tai hidastua muistin puutteeseen (ainoa poikkeus: jos joku urpoilee tekemällä tahallaan tai hölmöyttään web -sivun, jonka lataaminen tarvitsee gigatavuittain RAM -muistia).
Jostain syystä selainten kehittäjät eivät halua tuota tehdä, vaikka se olisi parasta, mitä selaintekniikalle voitaisiin tehdä. - Anonyymi
Anonyymi kirjoitti:
" 'jäi kaikki videot firefoxiin' - Mitähän tuokin tarkoittaa."
Ilmeisesti sitä, että ko. käyttäjä on Firefoxissa aina avannut uuden välilehden tai ikkunan kun on halunnut katsoa uuden videon, ja kaikki videoita sisältävät sivut ovat yhtäaikaa auki selaimessa.
Ja yleensä tuosta seuraa, se, että selaimilta loppuu muisti, kun selainten muistinhallinta on (M-Karin päinvastaiststa väitteistä huolimatta) huonosti tehty.
Ja kun selaimelta loppuu muisti, niin selain yleensä lakkaa reagoimasta näppäimistöltä ja/tai hiirellä annettuihin komentoihin, jolloin selaimelle ei voi tehdä muuta kuin (esim. Firefoxin tapauksessa) Windowsin tehtävänhallinnalla tappaa kaikki prosessit, joiden nimi on "firefox.exe".
Vinkki: JOS ja KUN joudut noin tekemään, kannattaa aloittaa se prosessien tappaminen siitä firefox.exe -prosessista, joka kuluttaa eniten RAM -muistia. Kun pahimman muistisyöpön tappaa ensin, myös muu windowsin toiminta (joka ei suoraan liity firefoxiin mitenkään) nopeutuu kummasti.
Olen ohjelmointipalstalla yrittänyt kysyä neuvoa, miten saisi firefoxin itse käännettyä lähdekoodista EXE -tiedostoksi, mutta ikävä kyllä tulee vain ns. v*ttuiluvastuksia.
Kas kun jos sen voisi itse kääntää, EHKÄ sille huonolle muistinhallinnallekin saisi jotakin tehtyä.
Minkähänlaisella C:n esiprosessorin (eli siis tekstipohjaisten makrojen) käytöllä saisi väännettyä asian niin, että jokainen osoitin korvataan virtuaaliosoittimella ?
siis jos koodissa on vaikkapa:
int *ptr_i;
int k;
niin kun koodissa lukee vaikkapa:
k = *ptr_i;
alunperinhän tuo lukee osoittimen ptr_i osoittamasta paikasta kokonaisluvun ja kopioi sen muuttujaan k.
Muutoksen jälkeen homman pitäisi toimia niin, että ptr_i ei ole enää absoluuttinen muistiosoite, vaan relatiivinen muistiosoite, joka on suhteellinen vaikkapa MEM_BASE -osoittimeen.
siis näin:
void* MEM_BASE;
Ja jos alunperin ptr_i on osoittanut johonkin muistipaikkaan suoraan, niin muutoksen jälkeen, jos tuo jokin muistipaikka on vaikkapa 8 tavua myöhemmin kuin MEM_BASE:n osoittama paikka, niin silloin (unsigned int)ptr_i == 8.
Ja sopivan tekstimakron avulla pitäisi saada homma toimimaan niin, että kun alkuperäisessä koodissa lukee k = *ptr_i; niin uusittuna vaikkapa:
k = *RELMEM(ptr_i);
Jossa tuo RELMEM -makro siis ottaa osoittimen MEM_BASE, lisää siihen ptr_i:n arvon, ja palauttaa summan void* -tyyppisenä.
Tuon lisäksi toki pitäisi saada aikaiseksi se, että kun ohjelma alunperin asettaa jonkin osoitteen tuohon ptr_i -osoittimeen, niin muutoksen jälkeen sen pitäisi asettaa ptr_i -muuttujaan tieto, montako tavua myöhemmin tuo haluttu osoite on verrattuna tuohon osoittimeen MEM_BASE.
Miksikö?
No koska tuolla tavalla voisi hoitaa homman niin, että tuon MEM_BASE:n arvoa voi halutessaan muuttaa, ja jopa niin, että kun MEM_BASE=NULL, niin silloin tiedetään, ettei mikään siihen relatiivinen osoitin ole sillä hetkellä käyettävissä suoraan, vaan ensin pitää palauttaa RAM -muistin sisältö väliaikaistiedostosta kiintolevyltä.
Tuohon kun saisi jotenkin ohjelmoitua sellaisen funktion, jota kutsutaan, jos tuo RELMEM -makro huomaa, että taustalla käytettävä MEM_BASE=NULL, ja vasta tun lisäfunktion suorituksen jälkeen muistiosoitus voi toteutua.
Tuo lisäfunktio siis lataa uudelleen RAMiin väliaikaistiedostosta kiintolevyltä sellaisen sisällön, joka on RAMista aiemmin poistettu.
Ideana siis, että vain yhden web -sivun sisältö kerrallaan on RAM -muistissa, ja jos on auki useita ikkunoita ja/tai välilehtiä, niin vain sen aktiivisen välilehden sisältö on RAM -muistissa, kaikkien muiden ikkunoiden ja/tai välilehtien sisältö on väliaikaistiedostosta kiintolevyllä.
Tuolla tekniikalla ihan sama vaikka avaisit 10 miljoonaa web -sivua samanaikaisesti, niin siltikin vain 1 web -sivun materiaali on kerrallaan RAM -muistissa, ja kun klikkaat eri välilehteä tai alt-TABin avulla menet eri selainikkunaan, niin äsken esillä ollut web -sivu laitetaan väliaikaistiedostoon kiintolevylle, ja uuden (klikatun tai ALT-TABitetun) web -sivun sivun sisältö ladataan RAMiin.
Näin minä haluaisin selaimen toimivan, koska silloin selain ei milloinkaan voi kaatua tai hidastua muistin puutteeseen (ainoa poikkeus: jos joku urpoilee tekemällä tahallaan tai hölmöyttään web -sivun, jonka lataaminen tarvitsee gigatavuittain RAM -muistia).
Jostain syystä selainten kehittäjät eivät halua tuota tehdä, vaikka se olisi parasta, mitä selaintekniikalle voitaisiin tehdä.Relatiivinen muistin osoitus selaimeen on kaunis ajatus, mutta vain ajatus. Käytännössä se ei toimisi ongelmitta ja koska käyttöjärjestelmä ja MMU jo tekevät juuri kuvailemaasi muistin uudelleenmäppäystä ja swappaamista levylle, koodimuutoksilla ei saavutettaisi mitään muuta kuin ehkä sen, että selaimen välilehdeltä toiselle siirtyminen saattaisi kestää ärsyttävän pitkään.
Relatiivisessa muistin osoituksessa on ohjelman kannalta myös käytännön ongelma. Yhden osoittimen sijaan ohjelmassa tulisi kuljettaa kahta osoitinta tms. (base, offset), mikä olisi todennäköisesti iso muutos koodiin ja myös iso lisäkuorma suoritettavaksi.
Relatiivisen muistin osoituksen laajaan käyttöön C-koodissa sisältyy vielä yksi ikävä ja ehkä vaikeasti hallittava riski. Standardifunktiot, käyttöjärjestelmän rajapintafunktiot ym. kirjastofunktiot eivät tue relatiivista muistin osoitusta vaan operoivat tavallisilla osoittimilla. Relatiivisia osoitteita joudutaan konvertoimaan absoluuttisiksi, mikä ei sinänsä ole ongelma. Tästä kuitenkin seuraa se, että ohjelmassa saattaa olla absoluuttisia osoitteita relatiivisiin muistilohkoihin ikäänkuin sovelluksen ulottumattomissa. Jos tällainen "pinned down" -muistilohko swapataan tai siirretään muistissa, saattaa syntyä vaikeasti selvitettäviä muistinkäsittelyvirheitä.
Relatiivinen muistin osoitus ei siis ole helppo ratkaisu pulmaan. Käyttöjärjestelmä ja MMU teorissa hoitavat homman, mutta miksi se ei toimi Firefoxissa kovin hyvin on mysteeri.
- Anonyymi
"Mitä tapahtuu jos unohdan vapauttaa allocatun muistin?"
Mikäli ohjelman suoritus päättyy siihen, ei tapahdu mitään normaalista poikkeavaa, mutta mikäli ohjelma varaa samalle prosessille uudestaan ja uudestaan tarvittavan tilan, todennäköisesti koko järjestelmä jää jumiin, mikään ei toimi. Virtakytkin on ainut joka silloin vapauttaa muistin.- Anonyymi
Windowsissa ainakin on niin, että ku prosessi lopetetaan, kaikki sen varaama muisti vapautuu, kaikki sen avaamat tiedostokahvat vapautetaan jne.
Toki, jos ohjelman suorituksen aikana varataan liikaa muistia niin tulee ongelmia.
Käytännössä (mahdollisia ohjelmointivirheitä lukuunottamatta) web -selaimet ovat ainoa ohjelmaryhmä, joka kärsii tuosta ongelmasta. - Anonyymi
Anonyymi kirjoitti:
Windowsissa ainakin on niin, että ku prosessi lopetetaan, kaikki sen varaama muisti vapautuu, kaikki sen avaamat tiedostokahvat vapautetaan jne.
Toki, jos ohjelman suorituksen aikana varataan liikaa muistia niin tulee ongelmia.
Käytännössä (mahdollisia ohjelmointivirheitä lukuunottamatta) web -selaimet ovat ainoa ohjelmaryhmä, joka kärsii tuosta ongelmasta.Hämärä muistikuva jostain pre-alloc:sta kernelissä, jonka avulla muistia on laitettu hiukan sivuun ja tavallaan pidetään muutama sivu muistia aina varalla. Jos tuo alkaa hupenemaan syntyy siitä jonkinlainen poikkeus ja kerneli ei toivon mukaan päädy kaatumaan vaan pystyy hoitamaan tilanteen noiden pre-alloc sivujensa avulla. Tarkoittanee, että muistin loppuminen ei kaada kerneliä vaan prosessin joka ylittää resurssinsa. Iso swap-tiedosto on tässä kohtaa se mikä hidastaa homman etanan vauhdilla eteneväksi. Tehtävää varten on prosessi "OOM Killer" joka alkaa arvottamaan prosesseja ja pistää niiltä nirrin pois niiden saaman oom-scoren perusteella, asiasta lisää:
https://rakeshjain-devops.medium.com/linux-out-of-memory-killer-31e477a45759
Aikaisemmin käytetty kernel panic on myöskin mahdollinen vaihtoehto, se pitää vaan nykyään kytkeä erikseen päälle.
- Anonyymi
GlobalAlloc
- Anonyymi
Muisti on halpaa. Miksei vaan osteta tarpeeksi muistia. Eihän Googlen spostiakaan tyhjennetä.
- Anonyymi
Muistia pitää olla riittävästi. Mutta huonon muistinkäsittelyn korjaaminen muistin määrää lisäämällä on kuin ruostevaurion korjaisi uudella maalikerroksella.
Liian moni softa nykyään on kirjoitettu siten kuin muistia olisi rajattomasti. Vaikka muisti on halpaa, sen tuhlaamisessa huonon ohjelmointiosaamisen vuoksi ei ole mitään järkeä.
- Anonyymi
Oikeasti tuollaisissa jos varaat jotain muistin on freealllocal.... tai vastaavia makroja, jotka vapauttavat, eivät tietenkään jos olet lukinnut muistin itse joten ei pysty sitä vapauttamaan kuten mitään grafiikkakiihdyttimen sisäistä RAM-muistiakaan ei pysty vapauttamaan ellet itse poista sitä tiettyyn fyysiseen muistiosoitteeseen lukittua muistipalikan pätkää hehehh :D
Ketjusta on poistettu 1 sääntöjenvastaista viestiä.
Luetuimmat keskustelut
Miehille kysymys
Onko näin, että jos miestä kiinnostaa tarpeeksi niin hän kyllä ottaa vaikka riskin pakeista ja osoittaa sen kiinnostukse1303639- 851865
Olen tosi outo....
Päättelen palstajuttujen perusteella mitä mieltä minun kaipauksen kohde minusta on. Joskus kuvittelen tänne selkeitä tap151661Haluaisin jo
Myöntää nämä tunteet sinulle face to face. En uskalla vain nolata itseäni enää. Enkä pysty elämäänkin näiden kanssa jos541372Ylen uutiset Haapaveden yt:stä.
Olipas kamalaa luettavaa kaupungin irtisanomisista. Työttömiä lisää 10 tai enempikin( Mieluskylän opettajat). Muuttavat1151216VENÄJÄ muuttanut tänään ydinasetroktiinia
Venäjän presidentti Vladimir Putin hyväksyi tiistaina päivitetyn ydinasedoktriinin, kertoo uutistoimisto Reuters. Sen mu911212- 681089
Kotkalainen Demari Riku Pirinen vangittu Saksassa lapsipornosta
https://www.kymensanomat.fi/paikalliset/8081054 Kotkalainen Demari Riku Pirinen vangittu Saksassa lapsipornon hallussapi281012- 66970
Hommaatko kinkkua jouluksi?
Itse tein pakastimeen n. 3Kg:n murekkeen sienillä ja juustokuorrutuksella. Voihan se olla, että jonkun pienen, valmiin k100964