RESOLVED - issue BATCH-1319: Small memory leak in StepSynchronizationManager

This commit is contained in:
dsyer
2009-07-05 14:42:17 +00:00
parent 0559b4f65e
commit 19942cc469
2 changed files with 41 additions and 19 deletions

View File

@@ -4,8 +4,10 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -17,10 +19,12 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
import org.springframework.util.ReflectionUtils;
public class StepSynchronizationManagerTests {
private StepExecution stepExecution = new StepExecution("step", new JobExecution(0L));
private StepExecution stepExecution = new StepExecution("step",
new JobExecution(0L));
@Before
@After
@@ -38,9 +42,10 @@ public class StepSynchronizationManagerTests {
}
@Test
public void testClose() {
public void testClose() throws Exception {
final List<String> list = new ArrayList<String>();
StepContext context = StepSynchronizationManager.register(stepExecution);
StepContext context = StepSynchronizationManager
.register(stepExecution);
context.registerDestructionCallback("foo", new Runnable() {
public void run() {
list.add("foo");
@@ -49,35 +54,51 @@ public class StepSynchronizationManagerTests {
StepSynchronizationManager.close();
assertNull(StepSynchronizationManager.getContext());
assertEquals(0, list.size());
// check for possible memory leak
assertEquals(0, extractStaticMap("counts").size());
assertEquals(0, extractStaticMap("contexts").size());
}
@SuppressWarnings("unchecked")
private Map extractStaticMap(String name) throws IllegalAccessException {
Field field = ReflectionUtils.findField(
StepSynchronizationManager.class, name);
ReflectionUtils.makeAccessible(field);
Map map = (Map) field.get(StepSynchronizationManager.class);
return map;
}
@Test
public void testMultithreaded() throws Exception {
StepContext context = StepSynchronizationManager.register(stepExecution);
StepContext context = StepSynchronizationManager
.register(stepExecution);
ExecutorService executorService = Executors.newFixedThreadPool(2);
FutureTask<StepContext> task = new FutureTask<StepContext>(new Callable<StepContext>() {
public StepContext call() throws Exception {
try {
StepSynchronizationManager.register(stepExecution);
StepContext context = StepSynchronizationManager.getContext();
context.setAttribute("foo", "bar");
return context;
}
finally {
StepSynchronizationManager.close();
}
}
});
FutureTask<StepContext> task = new FutureTask<StepContext>(
new Callable<StepContext>() {
public StepContext call() throws Exception {
try {
StepSynchronizationManager.register(stepExecution);
StepContext context = StepSynchronizationManager
.getContext();
context.setAttribute("foo", "bar");
return context;
} finally {
StepSynchronizationManager.close();
}
}
});
executorService.execute(task);
executorService.awaitTermination(1, TimeUnit.SECONDS);
assertEquals(context.attributeNames().length, task.get().attributeNames().length);
assertEquals(context.attributeNames().length, task.get()
.attributeNames().length);
StepSynchronizationManager.close();
assertNull(StepSynchronizationManager.getContext());
}
@Test
public void testRelease() {
StepContext context = StepSynchronizationManager.register(stepExecution);
StepContext context = StepSynchronizationManager
.register(stepExecution);
final List<String> list = new ArrayList<String>();
context.registerDestructionCallback("foo", new Runnable() {
public void run() {