Bonjour,
Je développe une application web (servlet) où le serveur doit envoyer des objets sérialisés (contenant des structures d'arbres dans mon cas) au client à travers des ObjectOutputStream.
Malheureusement dès que le client doit désérialiser les objets, sa mémoire explose et il n'est pas rare de me retrouver avec des OutOfMemoryError dès qu'un objet est un peu gros.
Par exemple pour un objet ayant une taille de 9mo, la désérialisation augmente la mémoire utilisé par mon client de 45 mo ! Une fois la désérialisation finie la mémoire utilisée revient à un niveau normal.
Voici le code côté servlet qui construit la réponse en sérialisant mon objet (applicationResponse):
et le code côté client qui reçoit la réponse et désérialise l'objet Response :
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 /** * Default behavior for sending the response content. * The Response object is entirely serialized and injected into the HttpServletResponse's body. * @param response the HttpServletResponse. * @param applicationResponse the response object to serialize. * @return the output stream of the HttpServletResponse. * @throws IOException */ private ServletOutputStream writeSerializedResponse(HttpServletResponse response, Response applicationResponse) throws IOException { response.setContentType("application/octet-stream"); response.addHeader(Response.CONTENT_TYPE_KEY, Response.CONTENT_TYPE); ServletOutputStream out = response.getOutputStream(); ObjectOutputStream objectOutput = new ObjectOutputStream(out); objectOutput.writeObject(applicationResponse); objectOutput.flush(); return out; }
La ligne Object obj = ois.readObject(); est celle qui me pose problème.
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
19
20
21
22
23
24
25
26 private Response readResponse(PostMethod method, ServerConnector serverConnector) throws FunctionalException { DataInputStream dis = null; ObjectInputStream ois = null; try { dis = new DataInputStream(method.getResponseBodyAsStream()); ois = new ObjectInputStream(dis); Object obj = ois.readObject(); if ( !(obj instanceof Response) ) { throw new TechnicalException("The server's response is not an instance of " + Response.class.getName()); } else { Response response = (Response)obj; /*... traitement...*/ } } finally { try { if ( ois != null ) ois.close(); if ( dis != null ) dis.close(); } catch(IOException ignore) {} } }
En profilant mon application je constate que juste avant celle-ci, la mémoire utilisée est à un niveau normal.
Par contre juste après cette ligne, celle-ci a explosé (typiquement une augmentation de 5 * taille de mon objet).
Est-ce normale que la méthode readObject() utilise autant de mémoire pour pouvoir s'éxécuter ? Ou est-ce moi qui fait quelque chose d'incorrect ?
Merci d'avance pour votre aide![]()
Partager