From: Krist on 5 Feb 2010 06:21 Hi all, As part of our reporting integrated with our JSF/JSP application, the report is converted to PDF then sent to browser for user to display. mean while during peak load our Heap usage could reach 3.5GB - 4GB. So I am suspecting the unclosed byteArrayInputStream is the cause. (This is a production application so I am collecting information before change the code) Is the unclosed() byteArrayInputStream really cause the problem ? (the codes is below) Thank you, Krist ByteArrayInputStream byteArrayInputStream = (ByteArrayInputStream) reportClientDoc.getPrintOutputController().export(exportOptions); reportClientDoc.close(); writeToBrowser(byteArrayInputStream, response, "application/csv", EXPORT_FILE); private void writeToBrowser(ByteArrayInputStream byteArrayInputStream, HttpServletResponse response, String mimetype, String exportFile) throws Exception { byte[] buffer = new byte[byteArrayInputStream.available()]; int bytesRead = 0; response.reset(); response.setHeader("Content-disposition", "inline;filename=" + exportFile); response.setContentType(mimetype); //Stream the byte array to the client. while((bytesRead = byteArrayInputStream.read(buffer)) != -1) { response.getOutputStream().write(buffer , 0, bytesRead);} //Flush and close the output stream. response.getOutputStream().flush(); response.getOutputStream().close(); }
From: Roedy Green on 5 Feb 2010 11:29 On Fri, 5 Feb 2010 03:21:04 -0800 (PST), Krist <krislioe(a)gmail.com> wrote, quoted or indirectly quoted someone who said : >Is the unclosed() byteArrayInputStream really cause the problem ? It is a big array of characters that holds the entire stream. How much of a problem it is unclosed depends on how big the stream it holds is. It is just a StringBuilder in disguise. Is there any reason you would NOT close the stream? -- Roedy Green Canadian Mind Products http://mindprod.com You can�t have great software without a great team, and most software teams behave like dysfunctional families. ~ Jim McCarthy
From: Kevin McMurtrie on 6 Feb 2010 01:33 In article <65da124a-3abd-4d57-9660-3c25784abe63(a)p13g2000pre.googlegroups.com>, Krist <krislioe(a)gmail.com> wrote: > Hi all, > > As part of our reporting integrated with our JSF/JSP application, the > report is converted to PDF then sent to browser for user to display. > mean while during peak load our Heap usage could reach 3.5GB - 4GB. So > I am suspecting the unclosed byteArrayInputStream is the cause. > (This is a production application so I am collecting information > before change the code) > > Is the unclosed() byteArrayInputStream really cause the problem ? > (the codes is below) > > Thank you, > Krist > > > > ByteArrayInputStream byteArrayInputStream = (ByteArrayInputStream) > > reportClientDoc.getPrintOutputController().export(exportOptions); > reportClientDoc.close(); > writeToBrowser(byteArrayInputStream, response, "application/csv", > EXPORT_FILE); > > private void writeToBrowser(ByteArrayInputStream byteArrayInputStream, > HttpServletResponse > response, String mimetype, String exportFile) > throws Exception { > byte[] buffer = new byte[byteArrayInputStream.available()]; > int bytesRead = 0; > response.reset(); > response.setHeader("Content-disposition", "inline;filename=" + > exportFile); > response.setContentType(mimetype); > //Stream the byte array to the client. > while((bytesRead = byteArrayInputStream.read(buffer)) != -1) > { response.getOutputStream().write(buffer , 0, > bytesRead);} > > //Flush and close the output stream. > response.getOutputStream().flush(); > response.getOutputStream().close(); > } This probably isn't where your memory is going. Turn on object histogram dumps then send a QUIT signal when memory is high. On the other hand, the code is bad: Casting the InputStream to an implementation is prone to failure. Don't. byte[] buffer = new byte[byteArrayInputStream.available()]; InputStream.available() returns a value between 0 and the entire size of the data. It's for avoiding blocking I/O and aligning buffers. It's not for setting up a constant buffer size. In the case of ByteArrayInputStream, it's the entire size of the data. Another implementation might return zero and then you'd infinite loop. Use a constant, like 2048 for WAN or 65536 for LAN. If the PrintOutputController belongs to you, consider modifying it to write directly to an OutputStream. This will eliminate intermediate buffering and provide a faster first-byte response. The downside is that the PrintOutputController could be active and holding resources for a very long time if the client is on dialup. Which is best depends on the application. -- I won't see Google Groups replies because I must filter them as spam
From: Krist on 6 Feb 2010 01:56 On 6 Feb, 13:33, Kevin McMurtrie <mcmurt...(a)pixelmemory.us> wrote: > In article > <65da124a-3abd-4d57-9660-3c25784ab...(a)p13g2000pre.googlegroups.com>, > > > > > > Krist <krisl...(a)gmail.com> wrote: > > Hi all, > > > As part of our reporting integrated with our JSF/JSP application, the > > report is converted to PDF then sent to browser for user to display. > > mean while during peak load our Heap usage could reach 3.5GB - 4GB. So > > I am suspecting the unclosed byteArrayInputStream is the cause. > > (This is a production application so I am collecting information > > before change the code) > > > Is the unclosed() byteArrayInputStream really cause the problem ? > > (the codes is below) > > > Thank you, > > Krist > > > ByteArrayInputStream byteArrayInputStream = (ByteArrayInputStream) > > > reportClientDoc.getPrintOutputController().export(exportOptions); > > reportClientDoc.close(); > > writeToBrowser(byteArrayInputStream, response, "application/csv", > > EXPORT_FILE); > > > private void writeToBrowser(ByteArrayInputStream byteArrayInputStream, > > HttpServletResponse > > response, String mimetype, String exportFile) > > throws Exception { > > byte[] buffer = new byte[byteArrayInputStream.available()]; > > int bytesRead = 0; > > response.reset(); > > response.setHeader("Content-disposition", "inline;filename=" + > > exportFile); > > response.setContentType(mimetype); > > //Stream the byte array to the client. > > while((bytesRead = byteArrayInputStream.read(buffer)) != -1) > > { response.getOutputStream().write(buffer , 0, > > bytesRead);} > > > //Flush and close the output stream. > > response.getOutputStream().flush(); > > response.getOutputStream().close(); > > } > > This probably isn't where your memory is going. Turn on object > histogram dumps then send a QUIT signal when memory is high. > > On the other hand, the code is bad: > > Casting the InputStream to an implementation is prone to failure. Don't. > > byte[] buffer = new byte[byteArrayInputStream.available()]; > > InputStream.available() returns a value between 0 and the entire size of > the data. It's for avoiding blocking I/O and aligning buffers. It's > not for setting up a constant buffer size. In the case of > ByteArrayInputStream, it's the entire size of the data. Another > implementation might return zero and then you'd infinite loop. Use a > constant, like 2048 for WAN or 65536 for LAN. > > If the PrintOutputController belongs to you, consider modifying it to > write directly to an OutputStream. This will eliminate intermediate > buffering and provide a faster first-byte response. The downside is > that the PrintOutputController could be active and holding resources for > a very long time if the client is on dialup. Which is best depends on > the application. > -- > I won't see Google Groups replies because I must filter them as spam- Sembunyikan teks kutipan - > > - Perlihatkan teks kutipan - Hi sir, When will the memory taken by the byteArrayInputStream will be released ? Will it be garbage collected ? Thanks, Krist
|
Pages: 1 Prev: Motivation of software professionals Next: port 8080 is used by java.exe |