Système.OutOfMemoryException: Exception du système de type'.OutOfMemoryException a été lancé à angularjs

j'ai passé quelques semaines à ce problème. mais je ne peux pas résoudre ce problème.

j'appelle un service API web en utilisant httpangularjs

           $http({
               method: 'GET',
               url: rootUrl + '/api/Project/ProjectList',
               headers: {
                   'Content-Type': "application/json; charset=utf-8"
               }
           }).success(function (response) {
               $scope.ProjectList = response;
           }).error(function (response, errorCode) {
               if (errorCode == 444) {
               }
           })

j'ai mis un point d'arrêt dans le codage côté serveur et client.

quand j'appelle le service, la méthode côté serveur va vite

ma méthode côté serveur (suis en Utilisant MVC, WEB API avec entity framework)

    [ActionName("ProjectList")]
    [HttpGet]   
    public IList<Project> ProjectList(Project projectModel)
    {
        return objIProjectService.ListOfProject();
    }

j'ai vérifié, le retour de service 8 enregistrements (8 lignes à partir de la base de données) avec un point de rupture objIProjectService.ListOfProject(); cette ligne.

tout va bien. Mais mon (réponse) http.success and http.error les fonctions de rappel frappent très lentement.

s'il vous Plaît voir l'image ci-dessous pour la performance, tandis que j'appelle le http méthode

enter image description here

Enfin http error function coup après 5 ou 10 minutes avec ce message d'erreur ci-dessous.

Système.OutOfMemoryException: Exception de type de Système.OutOfMemoryException " a été levée

C'est le problème. S'il vous plaît, dites-moi comment je peux résoudre ça?

en fait am a fait quelque chose pour cette question.

  • j'ai effacé le dossier temporaire-ne fonctionne pas
  • j'ai redémarré Visual studio et nettoyer la solution, redémarrer mon système et réparer visual studio.- ne fonctionne pas
  • mais si j'ai supprimé quelques lignes dans la base de données (j'utilise sql server 2008 r2 ), puis il travaille.

par exemple, si ma table de base de données a moins de 7 lignes, alors elle fonctionne rapidement sans cette erreur. Mais si ma table a plus de 8 rangs, alors elle fonctionne très lentement et a jeté l'erreur?? Pourquoi?? re pourriez-vous s'il vous plaît partager votre solution si vous avez collé cette question.

19
demandé sur Ramesh Rajendran 2015-05-02 09:23:27

5 réponses

je pense que le problème est que le serialiseur accède à toutes les propriétés connexes de votre classe de projet, donc plutôt que de retourner directement la classe Entity Framework, créez une nouvelle classe pour représenter les données que vous souhaitez envoyer via votre api (cherchez plus loin dans les classes DTO pour plus d'informations)

Vous pouvez utiliser le Select méthode Linq pour obtenir une liste de votre nouvelle classe dto remplie avec les données de votre appel EF.

var projects = objIProjectService.ListOfProject();

return projects.Select(p => new ProjectDTO() {
   ID = p.Id
   //... other properties of DTO class
}).ToList();

encore mieux, si vous mettez cette méthode select dans votre requête EF (i.e. context.projects.Select(/* select info here */).ToList(), vous pouvez vous assurer que EF ne ramène que les champs dont vous avez besoin

lors de la construction d'une API, vérifiez toujours la réponse JSON/XML, assurez-vous que les données sérialisées contiennent ce que vous attendiez qu'elles produisent. avec entity framework, cette réponse peut devenir énorme en parcourant toutes les tables associées, en retirant toutes les informations liées et en essayant de les sérialiser.

comme préférence personnelle I préférez toujours le retour d'un IHttpActionResult il vous permet de gérer ce qui est renvoyé au client surtout quand il y a des problèmes, le controller a un certain nombre de méthodes que vous pouvez utiliser pour créer cela c'est à dire OK(), BadRequest(), InternalServerError() ...

11
répondu Chris Warnes 2017-08-23 13:32:20

Ouvrez Sql Server machines profiller et montre EF généré des requêtes sql et des résultats. Et puis essayez d'exécuter sur la fenêtre sql ces requêtes brutes. Probablement vous ill comprendre après cela.

2
répondu Serdar KUŞ 2017-08-26 22:37:54

le problème ici est que la sérialisation de l'information prend beaucoup de temps. Vous accédez à toutes les classes connexes de votre classe de projet, ce qui peut causer des dommages importants lors de la gestion des aspects de mémoire.

vous pouvez résoudre cela de deux façons:

un est de retourner vos promesses et ensuite de récupérer les données:

 return $http({
               method: 'GET',
               url: rootUrl + '/api/Project/ProjectList',
               headers: {
                   'Content-Type': "application/json; charset=utf-8"
               }
           }).then(function (response) {

une deuxième option sera dans le code, en utilisant le framework Entity ou les requêtes linq.

utilisez les requêtes select pour réduisez la charge du côté serveur et du côté client comme suit:

    var projectsQuery = from p in ProjectModel as pm where pm.Id = p.Id select p.SomeValue
return projectsQuery 

de cette façon vous serez en mesure de réduire le fardeau des données sérialisation et pourrait éventuellement éviter la outOfMemoryExcexption.

il n'est pas nécessaire d'ouvrir le profileur Sql ici puisque les données du côté du serveur viennent à un moment raisonnable.

0
répondu Barr J 2017-08-27 12:22:26

la spécification HTTP N'impose pas de limite de taille spécifique pour les messages. Le problème avec les requêtes GET est que les paramètres sont inclus dans L'URL, qui est limitée en taille (cette limite dépend du navigateur et du serveur). N'utilisez pas une requête GET pour big data utilisez un POST one.

il y a un autre sujet si vous utilisez MVC et que vous travaillez sur le big data, vous avez besoin de l'utiliser.

<appSettings>
  <add key="aspnet:MaxJsonDeserializerMembers" value="150000" />
</appSettings>

ou

<system.webServer>
<security>
    <requestFiltering>
        <requestLimits maxAllowedContentLength="1000000" />
    </requestFiltering>
</security>

à partir de : MSDN

j'espère que cela va résoudre votre problème.

0
répondu Selman 2017-08-28 20:38:01

aller plus loin avec la suggestion de Chris Warnes et décrire la raison possible.

Laissez-moi deviner... vous utilisez entity framework avec chargement paresseux activé. Ainsi, lors de la sérialisation, toutes les propriétés de navigation que vous avez chargent des données de façon paresseuse et récursive parfois. Par exemple: Project contient Worker qui contient des références à même Project dans une propriété de navigation telle que WorkerProjects.

Serializer essaie de lui donner un sens, mais il ne peut pas, sans quelques allusions. la façon la plus simple de vérifier ce qui se passe, est de désactiver le chargement paresseux du framework entity et d'obtenir ce point de rupture là, juste après ToList() et juste avant le return.

BTW. Sérialiser ce genre de structure à JSON est en quelque sorte impossible. Vous devez avoir un mécanisme externe (tel que le cycle.js utilise XPath pour coder une telle référence) pour traiter les références et cycles dupliqués.

0
répondu Arek Bal 2017-08-29 19:39:03