1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.pool.impl;
19
20 import junit.framework.TestCase;
21 import junit.framework.TestSuite;
22 import org.apache.commons.pool.BasePoolableObjectFactory;
23 import org.apache.commons.pool.PoolableObjectFactory;
24
25 import java.util.Arrays;
26 import java.util.LinkedList;
27 import java.util.List;
28
29
30
31
32
33
34 public class TestSoftRefOutOfMemory extends TestCase {
35 private SoftReferenceObjectPool pool;
36
37 public TestSoftRefOutOfMemory(String testName) {
38 super(testName);
39 }
40
41 public static TestSuite suite() {
42 return new TestSuite(TestSoftRefOutOfMemory.class);
43 }
44
45 public void tearDown() throws Exception {
46 if (pool != null) {
47 pool.close();
48 pool = null;
49 }
50 System.gc();
51 }
52
53 public void testOutOfMemory() throws Exception {
54 pool = new SoftReferenceObjectPool(new SmallPoolableObjectFactory());
55
56 Object obj = pool.borrowObject();
57 assertEquals("1", obj);
58 pool.returnObject(obj);
59 obj = null;
60
61 assertEquals(1, pool.getNumIdle());
62
63 final List garbage = new LinkedList();
64 final Runtime runtime = Runtime.getRuntime();
65 while (pool.getNumIdle() > 0) {
66 try {
67 garbage.add(new byte[Math.min(1024 * 1024, (int)runtime.freeMemory()/2)]);
68 } catch (OutOfMemoryError oome) {
69 System.gc();
70 }
71 System.gc();
72 }
73 garbage.clear();
74 System.gc();
75
76 obj = pool.borrowObject();
77 assertEquals("2", obj);
78 pool.returnObject(obj);
79 obj = null;
80
81 assertEquals(1, pool.getNumIdle());
82 }
83
84 public void testOutOfMemory1000() throws Exception {
85 pool = new SoftReferenceObjectPool(new SmallPoolableObjectFactory());
86
87 for (int i = 0 ; i < 1000 ; i++) {
88 pool.addObject();
89 }
90
91 Object obj = pool.borrowObject();
92 assertEquals("1000", obj);
93 pool.returnObject(obj);
94 obj = null;
95
96 assertEquals(1000, pool.getNumIdle());
97
98 final List garbage = new LinkedList();
99 final Runtime runtime = Runtime.getRuntime();
100 while (pool.getNumIdle() > 0) {
101 try {
102 garbage.add(new byte[Math.min(1024 * 1024, (int)runtime.freeMemory()/2)]);
103 } catch (OutOfMemoryError oome) {
104 System.gc();
105 }
106 System.gc();
107 }
108 garbage.clear();
109 System.gc();
110
111 obj = pool.borrowObject();
112 assertEquals("1001", obj);
113 pool.returnObject(obj);
114 obj = null;
115
116 assertEquals(1, pool.getNumIdle());
117 }
118
119 public void testOutOfMemoryLarge() throws Exception {
120 pool = new SoftReferenceObjectPool(new LargePoolableObjectFactory(1000000));
121
122 Object obj = pool.borrowObject();
123 assertTrue(((String)obj).startsWith("1."));
124 pool.returnObject(obj);
125 obj = null;
126
127 assertEquals(1, pool.getNumIdle());
128
129 final List garbage = new LinkedList();
130 final Runtime runtime = Runtime.getRuntime();
131 while (pool.getNumIdle() > 0) {
132 try {
133 garbage.add(new byte[Math.min(1024 * 1024, (int)runtime.freeMemory()/2)]);
134 } catch (OutOfMemoryError oome) {
135 System.gc();
136 }
137 System.gc();
138 }
139 garbage.clear();
140 System.gc();
141
142 obj = pool.borrowObject();
143 assertTrue(((String)obj).startsWith("2."));
144 pool.returnObject(obj);
145 obj = null;
146
147 assertEquals(1, pool.getNumIdle());
148 }
149
150
151
152
153 public void testOutOfMemoryError() throws Exception {
154 pool = new SoftReferenceObjectPool(new BasePoolableObjectFactory() {
155 public Object makeObject() throws Exception {
156 throw new OutOfMemoryError();
157 }
158 });
159
160 try {
161 pool.borrowObject();
162 fail("Expected out of memory.");
163 }
164 catch (OutOfMemoryError ex) {
165
166 }
167 pool.close();
168
169 pool = new SoftReferenceObjectPool(new BasePoolableObjectFactory() {
170 public Object makeObject() throws Exception {
171 return new Object();
172 }
173
174 public boolean validateObject(Object obj) {
175 throw new OutOfMemoryError();
176 }
177 });
178
179 pool.returnObject(pool.borrowObject());
180
181 try {
182 pool.borrowObject();
183 fail("Expected out of memory.");
184 }
185 catch (OutOfMemoryError ex) {
186
187 }
188 pool.close();
189 }
190
191
192 public static class SmallPoolableObjectFactory implements PoolableObjectFactory {
193 private int counter = 0;
194
195 public Object makeObject() {
196 counter++;
197
198
199
200
201
202 return new String(String.valueOf(counter));
203 }
204 public boolean validateObject(Object obj) {
205 return true;
206 }
207 public void activateObject(Object obj) { }
208 public void passivateObject(Object obj) { }
209 public void destroyObject(Object obj) { }
210 }
211
212 public static class LargePoolableObjectFactory implements PoolableObjectFactory {
213 private String buffer;
214 private int counter = 0;
215
216 public LargePoolableObjectFactory(int size) {
217 char[] data = new char[size];
218 Arrays.fill(data, '.');
219 buffer = new String(data);
220 }
221
222 public Object makeObject() {
223 counter++;
224 return String.valueOf(counter) + buffer;
225 }
226 public boolean validateObject(Object obj) {
227 return true;
228 }
229 public void activateObject(Object obj) { }
230 public void passivateObject(Object obj) { }
231 public void destroyObject(Object obj) { }
232 }
233 }