001: /*
002: * TestPMMemory.java
003: *
004: * Created on October 13, 2006, 3:28 PM
005: *
006: * To change this template, choose Tools | Template Manager
007: * and open the template in the editor.
008: */
009: /*
010: * Licensed to the Apache Software Foundation (ASF) under one
011: * or more contributor license agreements. See the NOTICE file
012: * distributed with this work for additional information
013: * regarding copyright ownership. The ASF licenses this file
014: * to you under the Apache License, Version 2.0 (the
015: * "License"); you may not use this file except in compliance
016: * with the License. You may obtain a copy of the License at
017: *
018: * http://www.apache.org/licenses/LICENSE-2.0
019: *
020: * Unless required by applicable law or agreed to in writing,
021: * software distributed under the License is distributed on an
022: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
023: * KIND, either express or implied. See the License for the
024: * specific language governing permissions and limitations
025: * under the License.
026: */
027: package org.apache.openjpa.persistence.kernel;
028:
029: import java.util.Collection;
030: import java.util.Iterator;
031: import java.util.Map;
032:
033: import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
034:
035: import org.apache.openjpa.event.AbstractTransactionListener;
036: import org.apache.openjpa.event.TransactionEvent;
037: import org.apache.openjpa.event.TransactionListener;
038: import org.apache.openjpa.persistence.OpenJPAEntityManager;
039: import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
040: import org.apache.openjpa.persistence.OpenJPAQuery;
041:
042: public class TestPMMemory extends BaseKernelTest {
043:
044: /**
045: * Creates a new instance of TestPMMemory
046: */
047: public TestPMMemory() {
048: }
049:
050: public TestPMMemory(String s) {
051: super (s);
052: }
053:
054: public boolean skipTest() {
055: return true;
056: }
057:
058: private static final boolean _doPause = false;
059: private static final int NUM_OBJECTS = 2000;
060: private static final int NUM_FLUSHES = 5;
061:
062: // Hack to run stand alone.
063: public static void main(String[] args) throws Exception {
064: TestPMMemory testpm = new TestPMMemory("testPMMemory");
065: testpm.setUp();
066: testpm.testMemoryUse();
067: }
068:
069: public void setUp() {
070: System.out.println("About to delete all");
071: deleteAllStaged(getPM(), RuntimeTest1.class);
072: // deleteAll (RuntimeTest1.class);
073: System.out.println("Done delete all");
074: }
075:
076: public void deleteAllStaged(OpenJPAEntityManager pmArg,
077: Class classType) {
078: /*
079: // create 64000 objects
080: // now call this, WITH the datacache on,
081: // and despite using a fetchBatch size,
082: // this _will_ run out of memory
083: // props:
084: kodo.DataCache: true(CacheSize=5, SoftReferenceSize=1)
085: kodo.RemoteCommitProvider: sjvm
086: */
087: int delCount = 0;
088: OpenJPAEntityManager pm;
089:
090: boolean needToDelete = true;
091: while (needToDelete) {
092: pm = getPM();
093: startTx(pm);
094: //pm.setLargeTransaction(true);
095: pm.setTrackChangesByType(true);
096: String cstrng = classType.getName();
097: OpenJPAQuery kq = pm.createQuery("SELECT o FROM " + cstrng
098: + " o");
099: kq.getFetchPlan().setFetchBatchSize(100);
100: Collection results = (Collection) kq.getResultList();
101: if (results.size() == 0) {
102: needToDelete = false;
103: break;
104: }
105: System.out.println("We need to delete " + results.size());
106: Iterator iter = results.iterator();
107: while (iter.hasNext()) {
108: pm.remove(iter.next());
109: delCount += 1;
110: if ((delCount % 800) == 0) {
111: pm.flush();
112: // is the trans cahce now holding
113: // all these objects?
114: break;
115: }
116: }
117: System.out.print("deleted 200");
118: endTx(pm);
119: endEm(pm);
120: }
121: System.out.println("Done deleting");
122: }
123:
124: private void reportMemory() {
125: reportMemory("Memory used");
126: /*
127: DataCacheImpl dc;
128: dc = (DataCacheImpl) kpm.getConfiguration ().getDataCacheManager ().
129: getDataCache ()
130: CacheMap cacheMap = dc.getCacheMap ();
131: values/keySet
132: */
133: }
134:
135: private void reportMemory(String msg) {
136: System.gc();
137: long memUsed = Runtime.getRuntime().totalMemory();
138: long memFree = Runtime.getRuntime().freeMemory();
139: System.out.println("" + msg + " : " + memUsed + ", " + memFree);
140: }
141:
142: private void pause(double seconds) {
143: if (!_doPause)
144: return;
145: try {
146: Thread.currentThread().yield();
147: Thread.currentThread().sleep((int) seconds * 1000);
148: } catch (Exception e) {
149: }
150: }
151:
152: public void testMemoryUse() throws Exception {
153:
154: System.out
155: .println("Baseline, starting memory for N objects of "
156: + NUM_OBJECTS);
157: OpenJPAEntityManagerFactory kpmf = (OpenJPAEntityManagerFactory) getEmf();
158: OpenJPAEntityManager kpm = (OpenJPAEntityManager) kpmf
159: .createEntityManager();
160:
161: startTx(kpm);
162: int runningId = performAddsModifiesDeletes(kpm, NUM_OBJECTS, 0);
163: endTx(kpm);
164:
165: System.out.println("Baseline, starting memory ");
166: reportMemory();
167:
168: TransactionListener l = new AbstractTransactionListener() {
169: public void afterCommit(TransactionEvent ev) {
170: System.out.println("My Listener in afterCommit");
171: System.out.println("Num objects in transaction "
172: + ev.getTransactionalObjects().size());
173:
174: // send out an email confirming that the
175: // transaction was a success
176: }
177: };
178:
179: // kpm.registerListener (l);
180:
181: // jprobe, jprofiler.
182: // prefer treeview
183:
184: // Run a transaction for a whilw and report memory
185: startTx(kpm);
186: int objCount = 0;
187: for (int i = 0; i < NUM_FLUSHES; i++) {
188: System.out.println();
189: System.out.println("Iteration #" + i + " created "
190: + objCount);
191: reportMemory();
192: //kpm.setLargeTransaction(true);
193: kpm.setTrackChangesByType(true);
194: runningId = performAddsModifiesDeletes(kpm, NUM_OBJECTS,
195: runningId);
196: objCount += NUM_OBJECTS;
197: kpm.flush();
198: grabAllMemory();
199: // pause(30);
200: }
201:
202: System.out.println("Created objects, about to commit ()");
203: pause(90);
204: endTx(kpm);
205: pause(1);
206: System.out.println("Now commit ()");
207: reportMemory();
208: pause(33);
209: }
210:
211: protected void grabAllMemory() {
212: // exhaust all memory so that GC is run.
213: int size = 4096;
214: boolean grab = true;
215: int[] glob;
216: while (grab) {
217: try {
218: glob = new int[size];
219: size *= 2;
220: } catch (OutOfMemoryError e) {
221: System.out.println("Mem grabbed " + size);
222: grab = false;
223: glob = null;
224: }
225: }
226: glob = null;
227: }
228:
229: protected int performAddsModifiesDeletes(OpenJPAEntityManager pm,
230: int numObjects, int runningId) {
231: // pm should be active. Function does not perform commit.
232:
233: // Perform a series of transactions that will trigger adds,
234: // deletes, and udpates
235:
236: // create objects
237: RuntimeTest1[] persistables = new RuntimeTest1[numObjects];
238: for (int i = 0; i < persistables.length; i++) {
239: persistables[i] = new RuntimeTest1("foo #" + i, runningId
240: + i);
241: }
242: runningId += persistables.length;
243:
244: // add them
245: for (int i = 0; i < persistables.length; i++) {
246: pm.persist(persistables[i]);
247: }
248:
249: // modify them
250: for (int i = 0; i < persistables.length; i++) {
251: persistables[i].setIntField1(i + 1);
252: }
253:
254: /*
255: // delete them
256: for (int i = 0; i < persistables.length; i++)
257: {
258: pm.deletePersistent (persistables [i]);
259: }
260: */
261: return runningId + 1;
262: }
263:
264: static int _fetchGroupSerial = 0;
265:
266: protected OpenJPAEntityManagerFactory createDistinctFactory(
267: Class providerClass, String classProps1) {
268: Map props = null;
269:
270: //FIXME jthomas
271: /*
272: if (providerClass != null) {
273: props = new String[]{
274: "openjpa.RemoteCommitProvider", Configurations.getPlugin(
275: providerClass.getNameclassProps1),
276: // use this property to differentiate the factory
277: "openjpa.FetchGroups", "differentiatingFetchGroup" +
278: _fetchGroupSerial,
279: };
280: } else {
281: // No RCP
282: props = new String[]{
283: // use this property to differentiate the factory
284: "openjpa.RemoteCommitProvider", "sjvm",
285: "openjpa.FetchGroups", "differentiatingFetchGroup" +
286: _fetchGroupSerial,
287: };
288: }
289: _fetchGroupSerial += 1;
290: */
291:
292: return (OpenJPAEntityManagerFactory) getEmf(props);
293: }
294: }
|