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 java.util.Arrays;
21 import java.util.LinkedList;
22 import java.util.List;
23
24 import junit.framework.TestCase;
25
26 import org.apache.commons.pool.BasePoolableObjectFactory;
27 import org.apache.commons.pool.PoolableObjectFactory;
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 void tearDown() throws Exception {
42 if (pool != null) {
43 pool.close();
44 pool = null;
45 }
46 System.gc();
47 }
48
49 public void testOutOfMemory() throws Exception {
50 pool = new SoftReferenceObjectPool(new SmallPoolableObjectFactory());
51
52 Object obj = pool.borrowObject();
53 assertEquals("1", obj);
54 pool.returnObject(obj);
55 obj = null;
56
57 assertEquals(1, pool.getNumIdle());
58
59 final List garbage = new LinkedList();
60 final Runtime runtime = Runtime.getRuntime();
61 while (pool.getNumIdle() > 0) {
62 try {
63 long freeMemory = runtime.freeMemory();
64 if (freeMemory > Integer.MAX_VALUE) {
65 freeMemory = Integer.MAX_VALUE;
66 }
67 garbage.add(new byte[Math.min(1024 * 1024, (int)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 long freeMemory = runtime.freeMemory();
103 if (freeMemory > Integer.MAX_VALUE) {
104 freeMemory = Integer.MAX_VALUE;
105 }
106 garbage.add(new byte[Math.min(1024 * 1024, (int)freeMemory/2)]);
107 } catch (OutOfMemoryError oome) {
108 System.gc();
109 }
110 System.gc();
111 }
112 garbage.clear();
113 System.gc();
114
115 obj = pool.borrowObject();
116 assertEquals("1001", obj);
117 pool.returnObject(obj);
118 obj = null;
119
120 assertEquals(1, pool.getNumIdle());
121 }
122
123 public void testOutOfMemoryLarge() throws Exception {
124 pool = new SoftReferenceObjectPool(new LargePoolableObjectFactory(1000000));
125
126 Object obj = pool.borrowObject();
127 assertTrue(((String)obj).startsWith("1."));
128 pool.returnObject(obj);
129 obj = null;
130
131 assertEquals(1, pool.getNumIdle());
132
133 final List garbage = new LinkedList();
134 final Runtime runtime = Runtime.getRuntime();
135 while (pool.getNumIdle() > 0) {
136 try {
137 long freeMemory = runtime.freeMemory();
138 if (freeMemory > Integer.MAX_VALUE) {
139 freeMemory = Integer.MAX_VALUE;
140 }
141 garbage.add(new byte[Math.min(1024 * 1024, (int)freeMemory/2)]);
142 } catch (OutOfMemoryError oome) {
143 System.gc();
144 }
145 System.gc();
146 }
147 garbage.clear();
148 System.gc();
149
150 obj = pool.borrowObject();
151 assertTrue(((String)obj).startsWith("2."));
152 pool.returnObject(obj);
153 obj = null;
154
155 assertEquals(1, pool.getNumIdle());
156 }
157
158
159
160
161 public void testOutOfMemoryError() throws Exception {
162 pool = new SoftReferenceObjectPool(new BasePoolableObjectFactory() {
163 public Object makeObject() throws Exception {
164 throw new OutOfMemoryError();
165 }
166 });
167
168 try {
169 pool.borrowObject();
170 fail("Expected out of memory.");
171 }
172 catch (OutOfMemoryError ex) {
173
174 }
175 pool.close();
176
177 pool = new SoftReferenceObjectPool(new BasePoolableObjectFactory() {
178 public Object makeObject() throws Exception {
179 return new Object();
180 }
181
182 public boolean validateObject(Object obj) {
183 throw new OutOfMemoryError();
184 }
185 });
186
187 try {
188 pool.borrowObject();
189 fail("Expected out of memory.");
190 }
191 catch (OutOfMemoryError ex) {
192
193 }
194 pool.close();
195
196 pool = new SoftReferenceObjectPool(new BasePoolableObjectFactory() {
197 public Object makeObject() throws Exception {
198 return new Object();
199 }
200
201 public boolean validateObject(Object obj) {
202 throw new IllegalAccessError();
203 }
204
205 public void destroyObject(Object obj) throws Exception {
206 throw new OutOfMemoryError();
207 }
208 });
209
210 try {
211 pool.borrowObject();
212 fail("Expected out of memory.");
213 }
214 catch (OutOfMemoryError ex) {
215
216 }
217 pool.close();
218
219 }
220
221
222 public static class SmallPoolableObjectFactory implements PoolableObjectFactory {
223 private int counter = 0;
224
225 public Object makeObject() {
226 counter++;
227
228
229
230
231
232 return new String(String.valueOf(counter));
233 }
234 public boolean validateObject(Object obj) {
235 return true;
236 }
237 public void activateObject(Object obj) { }
238 public void passivateObject(Object obj) { }
239 public void destroyObject(Object obj) { }
240 }
241
242 public static class LargePoolableObjectFactory implements PoolableObjectFactory {
243 private String buffer;
244 private int counter = 0;
245
246 public LargePoolableObjectFactory(int size) {
247 char[] data = new char[size];
248 Arrays.fill(data, '.');
249 buffer = new String(data);
250 }
251
252 public Object makeObject() {
253 counter++;
254 return String.valueOf(counter) + buffer;
255 }
256 public boolean validateObject(Object obj) {
257 return true;
258 }
259 public void activateObject(Object obj) { }
260 public void passivateObject(Object obj) { }
261 public void destroyObject(Object obj) { }
262 }
263 }