Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 25
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    28

    Può un innocuo programmino javascript surriscaldare la CPU?

    Mi è successa una cosa strana, un po' preoccupante.
    Ho scritto un programmino in javascript che fa muovere un punto intorno a un centro con orbite che richiamano quelle di un elettrone intorno al nucleo, con la tecnica di modificare style.left e style.top.
    E fin qui nessun problema: il punto (che in realtà è un quadratino di 8x8 pixel) gira proprio come dovrebbe.
    Siccome però si vede solo il punto in movimento ma non la traccia delle orbite, ho fatto una piccola modifica: prima di applicare i nuovi valori di coordinate top e left al puntino orbitante, il programma crea un nuovo puntino (un nuovo tag <img>) con le vecchie coordinate, che rimane come traccia del passaggio a formare una scia delle orbite (non so se mi spiego).
    Anche questa cosa ha funzionato perfettamente, e infatti il programmino mostra proprio il puntino ruotante con orbite di aspetto simile a quelle degli elettroni intorno al nucleo (nell'iconografia divulgativa).
    Ero già piuttosto compiaciuto quando mi sono accorto di uno strano sovraccarico della CPU, che infatti dopo una decina di secondi dal caricamento nel browser del programmino sale al 100% di utilizzo, dove si stabilizza in modo permanente.
    Dopo una trentina di secondi la CPU si è già scaldata di oltre 15 gradi sopra i suoi valori normali e il software di controllo (speedfan nel mio caso) mostra frecce rosse, allarmi fuoco e fiamme da tutte le parti.
    Non so dire cosa potrebbe succedere alla CPU se lo lascissi girare per qualche minuto, perchè ci tengo alla mia macchina e non ci provo di sicuro, ma trovo la cosa alquanto preoccupante, anche perchè il tutto avviene in modo assolutamente silenzioso e solo in conseguenza di un programmino javascript che gira pacificamente nel browser e che tutto sommato avrei potuto caricare da qualsiasi sito.
    A qualcuno è già capitato qualcosa del gener? Quale può essere la causa?
    Non dovrebbe esserci una qualche misura di sicurezza del browser che impedisca un utilizzo tale da surriscaldare la CPU in modo critico?
    Per la precisione, la riga di codice che stressa la CPU è quella dove viene creato il nuovo elemento da lasciare come traccia. Finchè c'è un solo elemento che gira non ci sono problemi, ma quando il documento comincia ad essere popolato da centinaia di elementi, la CPU schizza al 100% (mentre l'occupazione di RAM rimane modesta, esattamente al contrario di quello che mi sarei aspettato, e non swappa neppure).

  2. #2
    Beh, da quello che so io - ma aspettiamo voci piu' esperte - javascript, come tutti i linguaggi interpretati - non e' leggerissimo.

    Da quello che so e' soprattutto critico per la memoria. E sicuramente il fatto di creare numerosi elementi va a sovraccaricare proprio la memoria. (Ma esattamente quanti? Lo script procede con la creazione ad libitum? Ogni quanto ne crei uno?)

    Non dovrebbe esserci una qualche misura di sicurezza del browser che impedisca un utilizzo tale da surriscaldare la CPU in modo critico?
    Sicuramente c'e' e sicuramente il tuo PC non andra' a fuoco (a meno che il BIOS non sia andato e non sia capace di spegnere il PC in caso di overheating )

    Per curiosita' posta il codice e vediamo se riescia fondere tutti i PC dei forumisti

    Ciao

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    28
    Ecco il codice nella versione innocua, con l'istruzione che stressa la CPU commentata.
    In questo modo si vede solo un quadratino (elettrone) che gira intorno a un quadrato più grande (nucleo), scommentando a proprio rischio l'istruzione traccia[punto++] = new riquadro('box0','img',nuovtop,nuovleft);, appaiono le orbite.
    Come si vede, la creazione di nuovi elementi è effettivamente ad libitum e piuttosto imponente. Stavo proprio cercando di capire l'impegno della RAM per studiare il modo migliore di gestirlo quando mi sono accorto che era invece la CPU ad andare in crisi in modo drammatico (chissà poi perchè la CPU e non la RAM).
    Comunque non sono un grande esperto di javascript e qualsiasi consiglio sarà molto apprezzato.
    codice:
    <html>
    <head>
    </head>
    <body id='box0'>
    <script language="JavaScript" type="text/javascript">
    <!--
    var vel_vert = -3; // Velocità verticale iniziale
    var acc_vert = 0;  // Accelerazione verticale
    var deltatop = 0;  // Spostamento verticale
    var vel_hor = 3;   // Velocità orizzontale iniziale
    var acc_hor = 0;   // Accelerazione orizzontale
    var deltaleft = 0; // Spostamento orizzontale 
    var traccia  = new Array();
    var punto=0;
    document.write('<div id = "orbitante" style="width: 8px; background: #777;');
    document.write('height: 8px; top: 200px; left: 300px; position: absolute"><div></div></div>');
    document.write('<div id = "nucleo" style="width: 20px; background: #000;');
    document.write('height: 20px; top: 300px; left: 500px; position: absolute"></div>');
    nucleo_x = 500;
    nucleo_y = 300;
    dist_base = 7000;
    coeff = 100;
    movimento();
    
    function movimento()
    { 
        lt = parseInt(orbitante.style.left);
        ot = parseInt(orbitante.style.top);
        d2 = Math.max((nucleo_y - ot)*(nucleo_y-ot)+(nucleo_x-lt)*(nucleo_x-lt),dist_base)
    
        acc_vert = coeff*(nucleo_y-ot)/d2;
        vel_vert = vel_vert + acc_vert;
        deltatop = deltatop + vel_vert;
        nuovtop  = ot + Math.floor(deltatop);    
        orbitante.style.top = nuovtop;
        deltatop = deltatop - Math.floor(deltatop); 
    
        acc_hor = coeff*(nucleo_x-lt)/d2;
        vel_hor = vel_hor + acc_hor;
        deltaleft = deltaleft + vel_hor;    
        nuovleft = lt + Math.floor(deltaleft);
        orbitante.style.left = nuovleft ;
        deltaleft = deltaleft - Math.floor(deltaleft);
    //    traccia[punto++] = new riquadro('box0',nuovtop,nuovleft);
        setTimeout('movimento()',1);
    }
    
    function riquadro(oParent,oNuovTop,oNuovLeft)
    {
    var contenitore = document.getElementById(oParent);
    this.riq = contenitore.appendChild(document.createElement('img'));
    this.riq.style.position = 'absolute';
    this.riq.style.width = 8;
    this.riq.style.height = 8;
    this.riq.style.left = oNuovLeft;
    this.riq.style.top = oNuovTop;
    this.riq.style.background = '#777'
    };
    //-->
    </script>
    </body>
    </html>

  4. #4
    Frontend samurai L'avatar di fcaldera
    Registrato dal
    Feb 2003
    Messaggi
    12,924
    secondo me è questa l'istruzione che genera il problema

    setTimeout('movimento()',1);

    1 millisecondo di intervallo significa stressare in modo esagerato la CPU. Prova a impostare almeno 10/20millisecondi e guarda se il problema si ripete (anche aumentando progressivamente i millisecondi eventualmente)
    Vuoi aiutare la riforestazione responsabile?

    Iscriviti a Ecologi e inizia a rimuovere la tua impronta ecologica (30 alberi extra usando il referral)

  5. #5
    Sicuramente far fare un'operazione al millisecondo e' retendere un po' troppo (in fondo vediamo solo 25 fotogrammi al secondo, no? Cioe' uno ogni 40 millisecondi)

    Ma il problema viene sono ritardato in quanto dopo un po' arrivi a creare circa 2000 elementi nella pagina e probabilmente gestire un'array di quelle dimensioni non e' agevole. (Tieni conto che gli array js non hanno dimensione fissa, per tanto ogni nuova aggiunta di un elemento richiede una totale lettura di tutta l'area di memoria occupata dall'array. E a volte va riallocato una nuova area di memoria per gestire un nuovo inserimento)

    Poi ho notato che se usi un div al posto di un img la cosa migliora un po'.

    Qualche variabile puo' essere definita solo localmente, anche questo aiuterebbe. Anzi potresti provare a portare tutte le variabili dentro la funzione.

    Comunque il mio PC non si e' fuso, tranquillo. Ma un po' in crisi c'e' andato.

    Ma soprattutto javascript non e' il linguaggio adatto per questo tipo di elaborazioni :-)

    Tienimi aggiornato

    Ciao

  6. #6
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    28
    Ho provato a diverse velocità:
    - a 10 ms è esattamente la stessa cosa, nel senso che il punto si muove alla stessa velocità che a 1 ms e la cpu surriscalda anche alla stessa velocità;
    - a 20 ms il punto rallenta vistosamente (circa 1/2 velocità), l'uso della CPU sembra più modesto all'inizio, ma da un certo punto in avanti l'utilizzo sale bruscamente dal 10% al 50% al 70% e si inchioda sul 100% cominciando a surriscaldare come prima.
    - a 50 ms rallenta in proporzione e anche la CPU sembra all'inizio meno impegnata, ma alla fine succede sempre la stessa cosa.

    L'impressione è che, a qualsiasi velocità, nel momento in cui si raggiunge un numero elevato di nuovi elementi creati, l'utilizzo della CPU si piazza al 100% e surriscalda.
    D'altra parte, se invece lascio commentata la riga che crea nuovi elementi, non c'è nessun impegno significativo di CPU (< 1%) neanche col timeout a 1 ms.

  7. #7
    Frontend samurai L'avatar di fcaldera
    Registrato dal
    Feb 2003
    Messaggi
    12,924
    Avrei alcune domande su questo script (visto anche l'ora, fatico a capirne le sfumature)
    esattamente perchè utilizzi l'array 'traccia'? Cioè tu utilizzi in altri punti quell'array?

    ogni volta che chiami (o meglio: istanzi) la funzione 'riquadro' crei un immagine e assegni il valore dell'appendchild a this.riq.

    Ma this.req esattamente che cos'è? Perchè io non saprei dirlo esattamente: è l'immagine che crei o il box che la contiene? E soprattutto perchè devi istanziare 'riquadro'? Non puoi semplicemente richiamare la funzione senza assegnarla a nulla?
    Vuoi aiutare la riforestazione responsabile?

    Iscriviti a Ecologi e inizia a rimuovere la tua impronta ecologica (30 alberi extra usando il referral)

  8. #8
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    28
    Sì hai ragione a questo punto l'array traccia[] non serve a niente lo posso anche togliere.
    Mi serviva in una prima versione dove settavo gli attributi di style nella funzione movimento(), con istruzioni del tipo: traccia[punto].riq.style.top = nuovtop;.
    Ma al momento di postare il codice ho preferito portare tutto nella funzione riquadro(), in modo da lasciare una sola riga da scommentare, a chi volesse farlo.
    E' però vero (chiedo scusa non me ne sono accorto) che a questo punto l'Array traccia[] e anche la variabile punto non servono più.
    Infatti ora ho provato a toglierli, lasciando solo la chiamata della funzione riquadro() e tutto gira esattamente come prima, purtroppo però anche la cpu surriscalda come prima.
    Riquadro() è una funzione di tipo generale (che di solito tengo in un file esterno funzvarie.js) che uso anche in altri programmi quando voglio crearmi un nuovo oggetto su cui definire eventualmente anche metodi specifici con prototype.
    Finora ha sempre funzionato egregiamente, ma come ho detto non sono espertissimo di javascript e in questo caso potrebbe benissimo esserci un modo migliore per fare la stessa cosa.
    This.riq è l'immagine che ho appena creato (ho creato un 'img' anzichè un 'div' per ovviare a un problemino con ie7, anche se 'div', come giustamente nota raven, andrebbe probabilmente meglio)

  9. #9
    Frontend samurai L'avatar di fcaldera
    Registrato dal
    Feb 2003
    Messaggi
    12,924
    allora se this.req è l'immagine prova a cambiare la funzione riquadro così

    codice:
    function riquadro(oParent,oNuovTop,oNuovLeft) {
    var contenitore = document.getElementById(oParent);
    var riq = document.createElement('img'); 
    riq.style.position = 'absolute';
    riq.style.width = 8px;
    riq.style.height = 8px;
    riq.style.left = oNuovLeft + 'px';
    riq.style.top = oNuovTop + 'px';
    riq.style.background = '#777'
    riq.src="#"; // dovresti definire un attributo src
    contenitore.appendChild(riq);
    };
    e richiamala senza 'new'
    Vuoi aiutare la riforestazione responsabile?

    Iscriviti a Ecologi e inizia a rimuovere la tua impronta ecologica (30 alberi extra usando il referral)

  10. #10
    Sto provando anche io... ho messo un alert ogni mille quadratini disegnati.

    Ne creo uno ogni 20ms.

    Mi pare che verso i 2000 la ventola del mio portatile (celeron 1700, non certo una potenza) vada al massimo. Niente fusione del nocciolo pero'.

    Ho provato varie combinazioni come quella di non chiamare new riquadro() ma di mettere tutto dentro movimento() ma non cambia molto.

    Evidentemente il grosso consumo di risorse e' dovuto alla difficolta' di aggiungere un elemento ad un elenco di altri 2000/3000 elementi. Ma non mi stupisco di tale comportamento.


    Anzi quasi quasi lo lascio andara ad libitum per vedere quando si impianta del tutto

    Buonanotte

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.