IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java ME Discussion :

Gestion de la memoire, Garbage Collector, tableau statique et ByteArrayOutputStream


Sujet :

Java ME

  1. #1
    Membre à l'essai
    Profil pro
    Analyste programmeur
    Inscrit en
    Avril 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : Finlande

    Informations professionnelles :
    Activité : Analyste programmeur

    Informations forums :
    Inscription : Avril 2003
    Messages : 79
    Points : 17
    Points
    17
    Par défaut Gestion de la memoire, Garbage Collector, tableau statique et ByteArrayOutputStream
    Bonjour tout le monde!
    Je developpe une application sur J2me avec Netbeans, elle a pour but d'afficher des images au format png qu'un serveur lui envoie.
    Je suis confronté à de serieux problemes de performances.
    J'ai repris cette application avant, pour la lecture des données (via un InputStream), on lisait octet par octet. Forcement c'etait plus lent, mais par contre ca n'obligeait pas d'allouer un tableau d'octet.
    En effet pour faire le lien un ByteArrayOutPutstream et un InputStream, je n'ai trouvé qu'un tableau de byte [].
    Dans ma version actuelle, j'alloue ce dernier à une taille maximal 100Ko (les images ne doivent pas depasser cette taille, le maximum qu ej'ai vu c'etait 77Ko).
    Je l'utilise donc comme tampon, mon algo :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    -allocation : byte[] tabByte = new byte[1024*100]
    -ouverture de la connection et des flux
    -intanciation : ByteArrayOutputStream baStream = new ByteArrayOutputStream()
    -gestion du protocole ....
    -reception des images :
        - lecture segmentée des données, on ne peut pas tout lire en une seule instruction 
        - les données lues à chaque boucle sont stockée temporairement dans tabByte
        - puis elles sont insérées dans baStream
    -creation de l'image avec Image.createImage (baStream.toByteArray())
    Mon probleme c'est que mon appli est vraiment trop gourmande, j'ai donc essayé de limité au mieux mes "depenses" en :
    - virant tous les message de debug (consommation de String)
    - tous les variables locales qui sont utilisées dans les methodes sont mise à "null"

    et j'ai dernierement essayé en lancant moi meme le Garbage Collector avec System.gc(), toutes les 100 images recues.
    Dans l'emulateur du WKT25, dans le moniteur de gestion de la memoire, je me retrouve avec un beau signal triangulaire (blagues d'electronicien ), alors que sans j'ai droit à une succession d'exponentielles.

    Ma question est simple, est ce que l'on peut / doit faire mieux ?
    L'appel au Garbage Collector est-il conseillé?

    Merci !

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par nonoRedDevils
    Ma question est simple, est ce que l'on peut / doit faire mieux ?
    Il faudrait surtout qu'on puisse voir ton code...

    Citation Envoyé par nonoRedDevils
    L'appel au Garbage Collector est-il conseillé?
    Non... Je pense que tu ne devrais pas avoir à te soucier de l'appeler...

    a++

  3. #3
    Membre à l'essai
    Profil pro
    Analyste programmeur
    Inscrit en
    Avril 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : Finlande

    Informations professionnelles :
    Activité : Analyste programmeur

    Informations forums :
    Inscription : Avril 2003
    Messages : 79
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par adiGuba
    Salut,
    Il faudrait surtout qu'on puisse voir ton code...
    malheureusement je ne peux pas le mettre, je bosse pour une boite, j'ai demandé à ma chef qui me l'a interdit.

    Non... Je pense que tu ne devrais pas avoir à te soucier de l'appeler...
    a++
    dans l'emulateur, je vois que la jvm fait appel à lui quand la memoire utilisée arrive à un seuil critique, ca pose un probleme si je le fais moi meme avant d'atteindre ce seuil ?

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    [QUOTE=nonoRedDevils]malheureusement je ne peux pas le mettre, je bosse pour une boite, j'ai demandé à ma chef qui me l'a interdit.


    Citation Envoyé par nonoRedDevils
    dans l'emulateur, je vois que la jvm fait appel à lui quand la memoire utilisée arrive à un seuil critique, ca pose un probleme si je le fais moi meme avant d'atteindre ce seuil ?
    Non... mais le GC devrait tourner de lui même lorsque c'est nécessaire.
    Le fait d'appeler toi même le GC ne rendra pas ton application moins gourmande...

    • Quel est le protocole utilisé pour récupérer les images ? Ne te permet-il pas de connaitre la taille du fichier avant de commencer la lecture ? Cela te permettrait d'optimiser le ByteArrayOutputStream afin d'éviter qu'il ne se redimensionne plusieurs fois...
    • De même, cela te permettrait d'utiliser directement un byte[] à la place de ByteArrayOutputStream, ce qui serait avantageux car toByteArray() crée un nouveau tableau en copie. Cela te permettrait également de faire une lecture directe...
    • Il faudrait également voir si les variables temporaires de la boucle ne pourraient pas être évité...


    Bref... Il faudrait bien voir l'algo et le code (et ce que cela implique en création d'objet temporaire) avant de se tourner vers le GC !

    Si l'appli est gourmande c'est surement parce que le GC est déjà en train de allouer/libérer beaucoup d'objet... Donc l'appeler directement n'améliorera pas forcément les perfs (cela peut même avoir l'effet inverse).

    Bon courage...

    a++

  5. #5
    Membre à l'essai
    Profil pro
    Analyste programmeur
    Inscrit en
    Avril 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : Finlande

    Informations professionnelles :
    Activité : Analyste programmeur

    Informations forums :
    Inscription : Avril 2003
    Messages : 79
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par adiGuba
    • Quel est le protocole utilisé pour récupérer les images ? Ne te permet-il pas de connaitre la taille du fichier avant de commencer la lecture ? Cela te permettrait d'optimiser le ByteArrayOutputStream afin d'éviter qu'il ne se redimensionne plusieurs fois...
    • si je connais la taille du fichier que je dois recevoir, en gros je recois un message de 12 octets, qui contient la taille du bloc de donnée qui suit ce message

    • De même, cela te permettrait d'utiliser directement un byte[] à la place de ByteArrayOutputStream, ce qui serait avantageux car toByteArray() crée un nouveau tableau en copie. Cela te permettrait également de faire une lecture directe...
    • Il faudrait également voir si les variables temporaires de la boucle ne pourraient pas être évité...
  6. en fait j'alloue deux tableau de facon statique dans le constructeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    bytearrayImg = new byte[1024*100];
    bytearrayMsg = new byte[1024];
    le premier me sert de tampon pour les images, l'autre de tampon pour les messages, je n'utilise plus de ByteArrayOutputStream, à tord ?
    Concernant les variables temporaires, j'ai essayé d'optimiser un max, avec l'instanciation dans le construceur, ou si je ne pouvais pas le faire, je mettais à "null" la variable local avant la fin de la méthode

    Bref... Il faudrait bien voir l'algo et le code (et ce que cela implique en création d'objet temporaire) avant de se tourner vers le GC !
    Si l'appli est gourmande c'est surement parce que le GC est déjà en train de allouer/libérer beaucoup d'objet... Donc l'appeler directement n'améliorera pas forcément les perfs (cela peut même avoir l'effet inverse).
    Bon courage...
    a++
    je te mets ci dessous un bout de code qui me sert à lire dans l'InputStream, et à stocker dans mes mon tableau l'image recu, pour les message c'est le meme code mais pas le meme tableau:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    //lecture d'une image ---->
    //sizeData est la taille du bloc de données
    //in_stream est l'InputStream
    int remaingbytes = sizeData;
    int read = 0;
    boolean arret = false;
    int totalread = 0;
    while(remaingbytes > 0)
    {
    read = in_stream.read(bytearrayImg, totalread, remaingbytes);
    if (read == -1)
    {
    arret = true;
    }
    remaingbytes = remaingbytes - read;  
    totalread += read;
    }

    merci de ton aide

  • #6
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par nonoRedDevils
    si je connais la taille du fichier que je dois recevoir, en gros je recois un message de 12 octets, qui contient la taille du bloc de donnée qui suit ce message
    Puisque tu connais la taille de l'image, tu peux optimiser ton tableau "bytearrayImg" afin qu'il n'utilise que ce qu'il a besoin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    byte[] bytearrayImg = new byte[sizeData];

    Citation Envoyé par nonoRedDevils
    je n'utilise plus de ByteArrayOutputStream, à tord ?
    Non : le ByteArrayOutputStream est très bien lorsque tu ne connais pas la taille exact de ce que tu vas lire, car il s'agrandit automatiquement et de manière transparente. Mais si tu connais la taille exacte c'est bien mieux de passer directement par un byte[]



    Sinon : tu fermes bien tes InputStream ? Dans des bloc finally ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    InputStream in_stream = // ouverture du flux
    try {
        // Traitements sur in_stream
    } finally {
        in_stream.close();
    }
    a++

  • #7
    Membre à l'essai
    Profil pro
    Analyste programmeur
    Inscrit en
    Avril 2003
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : Finlande

    Informations professionnelles :
    Activité : Analyste programmeur

    Informations forums :
    Inscription : Avril 2003
    Messages : 79
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par adiGuba
    Puisque tu connais la taille de l'image, tu peux optimiser ton tableau "bytearrayImg" afin qu'il n'utilise que ce qu'il a besoin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    byte[] bytearrayImg = new byte[sizeData];
    Non : le ByteArrayOutputStream est très bien lorsque tu ne connais pas la taille exact de ce que tu vas lire, car il s'agrandit automatiquement et de manière transparente. Mais si tu connais la taille exacte c'est bien mieux de passer directement par un byte[]
    en fait, désolé je me suis mal exprimer, je connais certes la taille de l'image qui va arriver, mais les tailles sont toutes differentes!


    Sinon : tu fermes bien tes InputStream ? Dans des bloc finally ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    InputStream in_stream = // ouverture du flux
    try {
        // Traitements sur in_stream
    } finally {
        in_stream.close();
    }
    a++
    non je ne fais pas de close, car mon appli est fait de la video, donc si tu veux j'ai besoin que mon inputStream reste ouvert tant que l'utilisateur est connecté au site

  • + Répondre à la discussion
    ActualitésFAQs JavaTutoriels JavaLivres JavaSources JavaOutils, EDI & API JavaJavaSearch

    Discussions similaires

    1. gestion d'allocation (similaire au garbage collector).
      Par SofEvans dans le forum Débuter
      Réponses: 26
      Dernier message: 25/08/2010, 14h08
    2. memoire garbage collector
      Par bruno.rotrou dans le forum ActionScript 3
      Réponses: 0
      Dernier message: 22/10/2009, 17h13
    3. [Gestion mémoire] Garbage collector, mais quand intervient-t-il ?
      Par jldgbu dans le forum Langages de programmation
      Réponses: 1
      Dernier message: 01/05/2008, 17h55
    4. Réponses: 7
      Dernier message: 26/04/2006, 16h16
    5. [Debutant]reallocation de memoire d'un tableau de type perso
      Par killerjeff dans le forum Débuter
      Réponses: 3
      Dernier message: 04/08/2004, 17h09

    Partager

    Partager
    • Envoyer la discussion sur Viadeo
    • Envoyer la discussion sur Twitter
    • Envoyer la discussion sur Google
    • Envoyer la discussion sur Facebook
    • Envoyer la discussion sur Digg
    • Envoyer la discussion sur Delicious
    • Envoyer la discussion sur MySpace
    • Envoyer la discussion sur Yahoo