système.outofmemoryexception Lors du remplissage DataAdapter?
Je dois tirer 150K
enregistrements à partir de la DB. Je suis à l'aide de da.Fill(ds,"Query")
et son lancement system.outofmemoryexception
.
Dim daGrid As New SqlDataAdapter(sqlcmd_q)
daGrid.Fill(dsGrid, "Query")
daGrid.Dispose()
J'ai besoin de cette datatable. Je ne peux pas utiliser le format XML. parce que j'ai besoin d'assigner à MSChartControl pour afficher ScotterPlot.
Des suggestions?
Acheter plus de mémoire 😉
Agréger les données d'une manière qui fait sens...
Quelle taille (en octets) sont ces documents?
Agréger les données d'une manière qui fait sens...
Quelle taille (en octets) sont ces documents?
OriginalL'auteur James123 | 2011-02-23
Vous devez vous connecter pour publier un commentaire.
La première chose que je voudrais vérifier est le nombre de colonnes que vous retournez, et quels sont leurs types de données. Bien que 150K records est un lot, il ne devrait pas vous donner une OOM exception, à moins que chaque enregistrement est d'environ 13K de longueur (sur une machine 32 bits). Cela me donne à penser que vous êtes de retour de manière plus de champs que vous avez besoin, ou peut-être que certains de ces champs sont très grandes chaînes ou des données binaires. Essayez de réduire l'instruction select pour retourner uniquement les champs qui sont absolument nécessaires pour l'affichage.
Si cela ne fonctionne pas, vous devrez les déplacer à partir d'une Table de données à une liste d'un type de données personnalisé (une classe avec les champs appropriés).
or perhaps that some of the fields are very large strings or binary data
Disons que vous disposez de 100 colonnes toutes définies commeVARCHAR(MAX)
mais aucune valeur n'est plus que de 10 caractères. Y aurait-il une différence que si le DB colonnes étaient tousVARCHAR(10)
? Je suppose que non. Seulement si les valeurs réelles dans les cellules ont été "très grande", à droite?corrigez - l'utilisation de la mémoire de type varchar(max) sur le client devrait être (plus ou moins) ce que les données réelles longueurs, pas de la taille de la colonne.
OriginalL'auteur Chris Shain
Vous n'avez pas spécifié de la requête. Assurez-vous qu'il contient uniquement les colonnes dont vous avez besoin.
Si vous avez encore des problèmes, vous pouvez essayez de passer en 64 bits (si votre matériel le supporte et si vous avez plus de 2 GO de mémoire libre).
Si cela ne fonctionne pas vous devez réduire l'encombrement mémoire. Une option possible serait de rendre l'intrigue sans enregistrer toute la base de données en mémoire. Il suffit de charger les données une par une, calculer les coordonnées et stocker ces sans stocker l'enregistrement sous-jacente. Peut-être que vous pouvez même laisser la requête ne sont que.
OriginalL'auteur TToni
Je sais que cette réponse est loin de la fin pour aider à l'affiche originale, mais mon espoir est que cela pourrait aider d'autres personnes qui ont un problème similaire.
Tout d'abord, c'est la
DataTable
c'est le problème de ne pas leDataAdapter
.Le problème est peut-être ce que vous êtes réellement hors de la mémoire (dans ce cas, ma réponse ne va pas aider). Vous pouvez faire le calcul pour déterminer si cela pourrait être le cas - nombre de dossiers x estimation d'octets par enregistrement. Si c'est de près de 2 go sur un 32 bits plate-forme ou votre quantité de RAM disponible sur une plateforme 64 bits, alors votre seule option est de réduire le nombre de dossiers, nombre de champs ou de trouver une approche qui utilise un objet DataReader au lieu d'une DataTable.
Dans votre cas, vous avez 150 dossiers, permet de supposer que chacun de 1 ko de mémoire, ce qui nous donne un chiffre rond de 150 MO. Même sur un ordinateur 32 bits avec 2 go de RAM qui devrait faire l'affaire (à condition il n'y a pas beaucoup de semblables allocations de mémoire). Dans votre cas, vous avez un ordinateur 64 bits avec 128 GO de RAM (nice). Donc, logiquement, vous ne devriez pas être sortir de la mémoire des erreurs.
Alors, quelle est l'origine du problème? C'est le Gros Tas d'Objets (LOH). Pourquoi? Le
DataTable
crée un tableau pour stocker les enregistrements. Ma compréhension est qu'il crée un tableau de 50 et se développe alors que les enregistrements sont ajoutés. Tout d'allocation de mémoire de plus de 85 000 octets viendra des tas d'objets volumineux. (Vous étiez sur une plateforme 64 bits, de sorte que les œuvres que une fois que vous frappez 10,625 enregistrements alors les allocations vont commencer à venir à partir du Tas d'Objets Volumineux.) Le problème avec le Tas d'Objets Volumineux, c'est qu'il n'est pas compacté. Alors il pourrait y avoir beaucoup d'espace libre, mais pas un seul bloc contigu qui est assez grand. Avec .net 4.5 de Microsoft s'est améliorée en termes de la coalescence adjacentes fragments, mais il ne sera pas réorganiser ces de créer de larges blocs d'espace libre. L'effet net est que, une fois que vous êtes dans la liturgie des heures dans mon expérience, c'est seulement une question de temps avant que vous obtenez un souvenir d'exception.La solution?
Ce qui a fonctionné pour moi a été de définir la capacité initiale de la
DataTable
. Lors de l'extraction des enregistrements de la base de données, cela signifie faire un nombre premier, si cela ne se fait au détriment d'une requête de base de données, puis:Alors que ce n'est pas d'éviter de verser dans la liturgie des heures, il devrait dire qu'il ne fait qu'une seule allocation au lieu de plusieurs. Donc, ainsi que l'évitement de la mémoire exception, vous devez également obtenir un gain de performance (compensé par la nécessité pour le supplément de requête de base de données).
Vous pouvez faire de la .net garbage collector compact le tas d'objets volumineux, mais vous ne pouvez dire à le faire la prochaine fois qu'il s'exécute. J'ai tendance à l'utiliser si je sais que je suis rentrer dans le tas d'objets volumineux. Cela peut-être exagéré, mais envisager de modifier ma suggestion faite ci-dessus:
OriginalL'auteur Brian Cryer