Evitez les plantages causés par une mauvaise utilisation de la librairie System.JSON

Embarcadero fournit une librairie puissante pour la gestion des données en format JSON. Ses fonctions principales se trouvent dans l'unité System.JSON

Certains choix technologiques dans son implémentation font qu'on peut parfois être un peu déboussolé. Il arrive que l'on se retrouve avec des violations d'accès alors que notre code source semble ok. On a ensuite tendance à incriminer les sources de la librairie mais en réalité cela provient généralement d'une mauvaise utilisation.

Voici donc quelques conseils pour une bonne utilisation de System.JSON et éviter des plantages de vos logiciels.

Le format JSON est une façon de gérer des données sous forme textuelle : des objets ayant des propriétés, des tableaux, des entiers, des décimaux, des chaînes et des booléens.

Pour traiter ces informations les fonctions de la librairie JSON retournent généralement un TJSONVariant. A nous de nous assurer du type attendu et de faire du transtypage pour utiliser le contenu. Pensez donc à intercepter les exceptions liées à des transtypages sur des données qui ne seraient pas dans le bon format.
Récupérer un tableau alors que c'est un objet est un signe que les données d'origine ne sont pas bonnes, il faut toujours tenir compte de cette hypothèse pour ne pas flinguer un traitement, surtout si vous utilisez des API provenant de services ou logiciels extérieurs.

Quand vous récupérez des informations dans un objet JSON, vous utilisez probablement GetValue(). Cette méthode est susceptible de planter si la valeur n'existe pas. Interceptez donc cette exception pour donner une valeur par défaut à vos variables ou utilisez TryGetValue().

Lorsque vous créez des éléments d'un objet JSON, n'en libérez pas systématiquement la mémoire ! Même chose quand l'une des fonctions de la librairie vous retourne un élément d'un autre élément JSON. Ce sont des sources de violations d'accès ultérieures (notamment à la libération de l'objet JSON global).
Sans doute pour des raisons d'optimisation de la mémoire la librairie JSON ne duplique pas les données en mémoire, elle se contente d'utiliser des pointeurs vers des zones que nous créons ou des zones qu'elle utilise. Si vous en libérez une partie, l'utilisation ou la libération de son conteneur générera une erreur.

Prenez par exemple un objet qui contiendrait 3 propriétés dont un tableau. Le code d'utilisation du tableau se présente habituellement comme une récupération de celui-ci, son parcours et la libération de la variable qui le contient. En faisant ça on rend l'objet incomplet et on génère une violation d'accès mémoire quelque part, ailleurs dans l'exécution du programme.

Soyez méfiants, n'oubliez pas que toutes les variables correspondant à une classe sont des pointeurs vers des zones mémoires. Ne libérez ces zones mémoires que si vous avez vraiment une raison de le faire.
Dans le doute, reportez vous à la documentation des méthodes utilisées ou directement à leur source. S'il y a duplication de données, libérez la mémoire, s'il y a juste un retour vers une zone existante, ne la libérez que si vous êtes sûr de ce que vous faites (en général abstenez-vous).

Pour faire vos tests, pensez à activer le rappel des zones mémoires non libérées en fin de programme. Il suffit de mettre ce code dans votre fiche principale. Vous découvrirez ainsi si vous loupez des choses.

Initialization

{$IFDEF DEBUG}
  System.ReportMemoryLeaksOnShutdown := true;
{$ENDIF}

end.

 


A lire aussi

Evitez les plantages causés par une mauvaise utilisation de la librairie System.JSON (18/04/2018)
Plutôt INI ou JSON pour stocker vos paramètres ? (21/07/2017)
Calculer et vérifier un checksum pour dialoguer avec l'extérieur (19/07/2017)
Télécharger simplement un fichier via Internet en tâche de fond (10/07/2017)
Calculer un MD5 sous Delphi (04/07/2017)
Les threads et le blocage des écrans (14/06/2017)
Utilisation de processus sous Delphi : fonctionnement de base. (04/06/2017)
Passer un traitement lourd en tâche de fond sans bloquer l'écran (04/06/2017)
Ajouter des chaînes de caractères vides dans un objet JSON (19/05/2017)
Configurer le firewall de McAfee AntiVirus Plus pour utiliser l'App Tethering (28/06/2016)

Membre du programme MVP.
Membre du programme MVP