/* * TestPMMemory.java * * Created on October 13, 2006, 3:28 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.openjpa.persistence.kernel; import java.util.Collection; import java.util.Iterator; import java.util.Map; import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1; import org.apache.openjpa.event.AbstractTransactionListener; import org.apache.openjpa.event.TransactionEvent; import org.apache.openjpa.event.TransactionListener; import org.apache.openjpa.persistence.OpenJPAEntityManager; import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory; import org.apache.openjpa.persistence.OpenJPAQuery; public class TestPMMemory extends BaseKernelTest { /** * Creates a new instance of TestPMMemory */ public TestPMMemory() { } public TestPMMemory(String s) { super(s); } public boolean skipTest() { return true; } private static final boolean _doPause = false; private static final int NUM_OBJECTS = 2000; private static final int NUM_FLUSHES = 5; // Hack to run stand alone. public static void main(String[] args) throws Exception { TestPMMemory testpm = new TestPMMemory("testPMMemory"); testpm.setUp(); testpm.testMemoryUse(); } public void setUp() { System.out.println("About to delete all"); deleteAllStaged(getPM(), RuntimeTest1.class); // deleteAll (RuntimeTest1.class); System.out.println("Done delete all"); } public void deleteAllStaged(OpenJPAEntityManager pmArg, Class classType) { /* // create 64000 objects // now call this, WITH the datacache on, // and despite using a fetchBatch size, // this _will_ run out of memory // props: kodo.DataCache: true(CacheSize=5, SoftReferenceSize=1) kodo.RemoteCommitProvider: sjvm */ int delCount = 0; OpenJPAEntityManager pm; boolean needToDelete = true; while (needToDelete) { pm = getPM(); startTx(pm); //pm.setLargeTransaction(true); pm.setTrackChangesByType(true); String cstrng = classType.getName(); OpenJPAQuery kq = pm.createQuery("SELECT o FROM " + cstrng + " o"); kq.getFetchPlan().setFetchBatchSize(100); Collection results = (Collection) kq.getResultList(); if (results.size() == 0) { needToDelete = false; break; } System.out.println("We need to delete " + results.size()); Iterator iter = results.iterator(); while (iter.hasNext()) { pm.remove(iter.next()); delCount += 1; if ((delCount % 800) == 0) { pm.flush(); // is the trans cahce now holding // all these objects? break; } } System.out.print("deleted 200"); endTx(pm); endEm(pm); } System.out.println("Done deleting"); } private void reportMemory() { reportMemory("Memory used"); /* DataCacheImpl dc; dc = (DataCacheImpl) kpm.getConfiguration ().getDataCacheManager (). getDataCache () CacheMap cacheMap = dc.getCacheMap (); values/keySet */ } private void reportMemory(String msg) { System.gc(); long memUsed = Runtime.getRuntime().totalMemory(); long memFree = Runtime.getRuntime().freeMemory(); System.out.println("" + msg + " : " + memUsed + ", " + memFree); } private void pause(double seconds) { if (!_doPause) return; try { Thread.currentThread().yield(); Thread.currentThread().sleep((int) seconds * 1000); } catch (Exception e) { } } public void testMemoryUse() throws Exception { System.out.println("Baseline, starting memory for N objects of " + NUM_OBJECTS); OpenJPAEntityManagerFactory kpmf = (OpenJPAEntityManagerFactory) getEmf(); OpenJPAEntityManager kpm = (OpenJPAEntityManager) kpmf.createEntityManager(); startTx(kpm); int runningId = performAddsModifiesDeletes(kpm, NUM_OBJECTS, 0); endTx(kpm); System.out.println("Baseline, starting memory "); reportMemory(); TransactionListener l = new AbstractTransactionListener() { public void afterCommit(TransactionEvent ev) { System.out.println( "My Listener in afterCommit"); System.out.println( "Num objects in transaction " + ev.getTransactionalObjects().size()); // send out an email confirming that the // transaction was a success } }; // kpm.registerListener (l); // jprobe, jprofiler. // prefer treeview // Run a transaction for a whilw and report memory startTx(kpm); int objCount = 0; for (int i = 0; i < NUM_FLUSHES; i++) { System.out.println(); System.out.println("Iteration #" + i + " created " + objCount); reportMemory(); //kpm.setLargeTransaction(true); kpm.setTrackChangesByType(true); runningId = performAddsModifiesDeletes(kpm, NUM_OBJECTS, runningId); objCount += NUM_OBJECTS; kpm.flush(); grabAllMemory(); // pause(30); } System.out.println("Created objects, about to commit ()"); pause(90); endTx(kpm); pause(1); System.out.println("Now commit ()"); reportMemory(); pause(33); } protected void grabAllMemory() { // exhaust all memory so that GC is run. int size = 4096; boolean grab = true; int[] glob; while (grab) { try { glob = new int[size]; size *= 2; } catch (OutOfMemoryError e) { System.out.println("Mem grabbed " + size); grab = false; glob = null; } } glob = null; } protected int performAddsModifiesDeletes(OpenJPAEntityManager pm, int numObjects, int runningId) { // pm should be active. Function does not perform commit. // Perform a series of transactions that will trigger adds, // deletes, and udpates // create objects RuntimeTest1[] persistables = new RuntimeTest1[numObjects]; for (int i = 0; i < persistables.length; i++) { persistables[i] = new RuntimeTest1("foo #" + i, runningId + i); } runningId += persistables.length; // add them for (int i = 0; i < persistables.length; i++) { pm.persist(persistables[i]); } // modify them for (int i = 0; i < persistables.length; i++) { persistables[i].setIntField1(i + 1); } /* // delete them for (int i = 0; i < persistables.length; i++) { pm.deletePersistent (persistables [i]); } */ return runningId + 1; } static int _fetchGroupSerial = 0; protected OpenJPAEntityManagerFactory createDistinctFactory( Class providerClass, String classProps1) { Map props = null; //FIXME jthomas /* if (providerClass != null) { props = new String[]{ "openjpa.RemoteCommitProvider", Configurations.getPlugin( providerClass.getNameclassProps1), // use this property to differentiate the factory "openjpa.FetchGroups", "differentiatingFetchGroup" + _fetchGroupSerial, }; } else { // No RCP props = new String[]{ // use this property to differentiate the factory "openjpa.RemoteCommitProvider", "sjvm", "openjpa.FetchGroups", "differentiatingFetchGroup" + _fetchGroupSerial, }; } _fetchGroupSerial += 1; */ return (OpenJPAEntityManagerFactory) getEmf(props); } }