Problèmes de performances Apache Poi dans le traitement de plusieurs demandes

J’essaie d’écrire les données de la table de firebase database dans un fichier Xlsx en utilisant Apache Poi. Au début, je l’ai essayé avec XSSFWorkbook. Je voulais écrire près d’un million de tuples avec chacun près de 100 atsortingbuts. J’ai donc eu l’erreur OutOfMemory lors de l’utilisation de XSSFWorkbook, car il charge l’intégralité des données en mémoire avant d’écrire.

J’ai donc essayé d’utiliser SXSSFWorkbook . Il prend en charge le streaming, il n’y a donc aucun problème avec l’utilisation de la mémoire. Cela fonctionne très bien quand il y a une demande de client unique. Pour être précis, il a fallu presque 1 minute et 30 secondes pour répondre (dans le cas d’un seul client). J’utilise un serveur apache tomcat 8.5.32 dans ma machine.

Je comprends de la documentation apache que le SXSSFWorkbook conserve seulement une quantité spécifiée de lignes en mémoire et écrit les autres dans un fichier temporaire.

Il y a deux parties dans mon code.

SXSSFWorkbook wb = new SXSSFWorkbook(100); Sheet sh = wb.createSheet(); Ssortingng name = UUID.randomUUID().toSsortingng().replace("-", "") + ".xlsx"; try { Ssortingng sql = "select * from users"; ResultSet rs = stmt.executeQuery(sql); System.out.println("Query finished"); int i=1; while(rs.next()) { User user = getUserByRS(rs); Row row = sh.createRow(i++); Cell cell1 = row.createCell(0); cell1.setCellValue(user.getUid()); for(int j=1;j<100;j+=2) { Cell cell2 = row.createCell(j); cell2.setCellValue(user.getUsername()); Cell cell3 = row.createCell(j+1); cell3.setCellValue(user.getText()); } if(i%40000==0) { Date mydate = new Date(); System.out.println( (i/4000) + "% completed" + " System date : "+ mydate.toString()); out.println( (i/4000) + "% completed" + " System date : "+ mydate.toString()); out.println(Runtime.getRuntime().totalMemory() + " " + Runtime.getRuntime().freeMemory()); System.gc(); } } 

C’est la première partie de mon code. Ce code extrait les données de la firebase database (le stream de données provenant de la firebase database a été traité dans la requête SQL. Pas de problèmes de mémoire ici) et les écrit dans SXXFSWorkbook, qui écrit les données dans un fichier de disque temporaire intermédiaire. Cette partie du code prend près de 40 secondes en cas de demande d’un seul client et presque 5 à 6 minutes en cas de demande de 6 à 8 clients (Ensemble). Pourquoi?.

Venir à la deuxième partie de mon code.

  FileOutputStream out1 = new FileOutputStream(new File("/Users/test/Desktop/reports/" + name)); wb.write(out1); out1.close(); 

C’est la partie du code où les données du fichier disque intermédiaire sont écrites dans le stream de sortie de mon fichier de réponses. Cela prend près de 40 secondes dans le cas d’un fichier unique et d’environ 10 à 11 minutes dans le cas de 6 à 8 demandes client. Pourquoi?

En outre, la vitesse varie en fonction du nombre de lignes chargées en mémoire. Par exemple, dans le cas de 100 lignes, il faut environ 20 minutes pour traiter 6 à 8 demandes de clients, alors qu’il faut environ 12 à 15 minutes pour 10 lignes. Pourquoi?

De plus, le fichier de réponses pour toutes les demandes est écrit simultanément. Puisque le serveur traite chaque requête en tant que thread séparé, pourquoi cela se produit-il?