Bonjour,
J'aimerais avoir votre avis sur le code suivant, je pense que j'ai une fuite de mémoire quelque part. en effet l'outil jvisualvm me donne les graphes suivant lorsque je lance mon programme.
Comme vous voyez, l'activité du GC est à 0%, les max du heap utilisé est dans un sens croissant, avec le temps j'ai une exception de java heap space OutOfMemory.
Ci dessous mon code, il consiste à chaque "itération" de spring schudeler de lancer la création d'un fichier excel.
context-app.xml
context-datasource.xml
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 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd"> <import resource="classpath:config/context-datasource.xml"/> <bean id="mainExample" class="com.spring.main.MainExample"> <property name="actorDao" ref="actorDao"></property> </bean> <task:scheduled-tasks> <task:scheduled ref="mainExample" method="selectActor" cron="*/2 * * * * *" /> </task:scheduled-tasks> </beans>
Schudeler.java
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
27
28
29 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:property-placeholder location="classpath:config/global.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp.ManagedBasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driver.class}" /> <property name="url" value="${url.datasource}" /> <property name="username" value="${username.datasource}" /> <property name="password" value="${password.datasource}" /> <property name="initialSize" value="${pool.init.size}"/> <property name="maxActive" value="${pool.max.active}"/> <property name="removeAbandoned" value="${pool.remove.abandoned}"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="actorDao" class="com.spring.main.ActorDao"> </bean> </beans>
MainnExample.java
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 public class Schudeler { public static void main( String[] args ) { Logger logger = LoggerFactory.getLogger(Schudeler.class); logger.info("Démarrage du schudeler "); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:config/context-app.xml"); } }
ActorDao.java
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 package com.spring.main; import java.util.List; import java.util.Map; import java.util.Random; public class MainExample { String[] dates =new String[]{"2018-06-03", "2018-05-27", "2018-05-30", "2018-05-28", "2018-05-29"}; private ActorDao actorDao; public void setActorDao(ActorDao actorDao) { this.actorDao = actorDao; } /** * */ public void selectActor(){ if(actorDao!=null){ String date = dates[getRandomIndex(dates.length)]; List<Map<String, Object>> actors = actorDao.getListeActors(date); if(actors!=null && actors.size() > 0){ System.out.println("Number of actors is : " + actors.size()); String filename = getFilename(date); //Export XLS XlsxItemWriter writer = new XlsxItemWriter(filename); try { writer.write(actors); System.out.println("Actors with birthay : " + date); } catch (Exception e) { System.out.println(e.getMessage()); } } } } private String getFilename(String date){ String sdate = date.replaceAll("-", ""); StringBuilder sb = new StringBuilder("e:/export/"); sb.append(sdate); sb.append(".xlsx"); return sb.toString(); } private int getRandomIndex(int max){ int r = 0; Random random = new Random(); r = random.nextInt(max); return r; } }
XlsxItemWriter .java
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 package com.spring.main; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; import com.spring.beans.ActorBean; public class ActorDao { public List<Map<String, Object>> getListeActors(String date){ List<Map<String, Object>> liste = null; try(ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:config/context-datasource.xml")){ JdbcTemplate jdbcTemplate = (JdbcTemplate)ctx.getBean("jdbcTemplate"); liste = jdbcTemplate.queryForList("SELECT * FROM `actor` WHERE date(?)=birthay", date); } return liste; } }
En commentant l'appel à XlsxItemWriter, tout semble normal, donc c'est le code qui génère cette fuite de mémoire.
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 package com.spring.main; import java.io.FileOutputStream; import java.util.List; import java.util.Map; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; public class XlsxItemWriter { private String outputFilename; private Workbook workbook; private int currRow = 0; public XlsxItemWriter(String _outputFilename) { this.outputFilename = _outputFilename; } private void createStringCell(Row row, String val, int col) { Cell cell = row.createCell(col); cell.setCellValue(val); } public void write(List<Map<String, Object>> items) throws Exception { workbook = new SXSSFWorkbook(1000); workbook.createSheet(); Sheet sheet = workbook.getSheetAt(0); for(Map<String, Object> map : items){ int c = 0; if(currRow==0){ Row row = sheet.createRow(currRow); for(Object o : map.keySet()){ createStringCell(row, o!=null ? o.toString() : "", c); c++; } currRow++; } Row row = sheet.createRow(currRow); c = 0; for(Object o : map.keySet()){ createStringCell(row, map.get(o)!=null ? map.get(o).toString() : "", c); c++; } currRow++; } FileOutputStream fos = new FileOutputStream(outputFilename); workbook.write(fos); fos.close(); fos.flush(); } }
Qu'est ce qui me manque pour rendre ce code performant ?
Merci
Partager