free() alloc()

Anonyymi

Mitä tapahtuu jos unohdan vapauttaa allocatun muistin?

15

1324

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • 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

    1. Naiset miltä kiihottuminen teissä tuntuu

      Kun miehellä tulee seisokki ja ja sellainen kihmelöinti sinne niin mitä naisessa köy? :)
      Sinkut
      71
      5100
    2. Haistoin ensin tuoksusi

      Käännyin katsomaan oletko se todellakin sinä , otin askeleen taakse ja jähmetyin. Moikattiin naamat peruslukemilla. Tu
      Ikävä
      16
      2357
    3. Olet sä kyllä

      ihme nainen. Mikä on tuo sun viehätysvoiman salaisuus?
      Ikävä
      25
      1867
    4. Teuvo Hakkaraisesta tulee eurovaalien ääniharava

      Persuissa harmitellaan omaa tyhmyyttä
      Maailman menoa
      44
      1568
    5. Hiljaiset hyvästit?

      Vai mikä on :( oonko sanonut jotain vai mitä?
      Ikävä
      12
      1561
    6. Miksi kohtelit minua kuin tyhmää koiraa?

      Rakastin sinua mutta kohtelit huonosti. Tuntuu ala-arvoiselta. Miksi kuvittelin että joku kohtelisi minua reilusti. Hais
      Särkynyt sydän
      5
      1348
    7. Turha mun on yrittää saada yhteyttä

      Oot mikä oot ja se siitä
      Suhteet
      9
      1267
    8. Kyllä poisto toimii

      Esitin illan suussa kysymyksen, joka koska palstalla riehuvaa häirikköä ja tiedustelin, eikö sitä saa julistettua pannaa
      80 plus
      3
      1195
    9. "Joka miekkaan tarttuu, se siihen hukkuu"..

      "Joka miekkaan tarttuu, se siihen hukkuu".. Näin puhui jo aikoinaan Jeesus, kun yksi hänen opetuslapsistaan löi miekalla
      Yhteiskunta
      7
      1187
    10. Näkymätöntä porukkaa vai ei

      Mon asuu yksin. Mitas mieltä ootte ?
      Ikävä
      14
      1173
    Aihe