| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.testing.tests.identitymaps; |
| |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| import org.eclipse.persistence.internal.identitymaps.CacheKey; |
| import org.eclipse.persistence.internal.identitymaps.WeakIdentityMap; |
| import org.eclipse.persistence.queries.InsertObjectQuery; |
| import org.eclipse.persistence.testing.models.employee.domain.Employee; |
| import org.eclipse.persistence.testing.framework.*; |
| |
| //bug4649617 Test if there is any memory leak in InsertObjectQuery with WeakIdentityMap. |
| public class InsertWeakIdentityMapTest extends TestCase { |
| protected Class originalIdentityMapClass; |
| protected int originalIdentityMapSize; |
| protected int identityMapSize = 10; |
| |
| public InsertWeakIdentityMapTest() { |
| setDescription("Test if there is any memory leak in InsertObjectQuery with WeakIdentityMap."); |
| } |
| |
| protected WeakIdentityMap getIdentityMap() { |
| return (WeakIdentityMap)getAbstractSession().getIdentityMapAccessorInstance().getIdentityMap(Employee.class); |
| } |
| |
| @Override |
| public void reset() { |
| getSession().getDescriptor(Employee.class).setIdentityMapClass(originalIdentityMapClass); |
| getSession().getDescriptor(Employee.class).setIdentityMapSize(originalIdentityMapSize); |
| getSession().getIdentityMapAccessor().initializeIdentityMaps(); |
| } |
| |
| @Override |
| public void setup() { |
| originalIdentityMapClass = getSession().getDescriptor(Employee.class).getIdentityMapClass(); |
| originalIdentityMapSize = getSession().getDescriptor(Employee.class).getIdentityMapSize(); |
| getSession().getDescriptor(Employee.class).setIdentityMapClass(WeakIdentityMap.class); |
| getSession().getDescriptor(Employee.class).setIdentityMapSize(identityMapSize); |
| getSession().getIdentityMapAccessor().initializeIdentityMaps(); |
| } |
| |
| @Override |
| public void test() { |
| for (int index = 0; index < (identityMapSize * 2); index++) { |
| Employee obj = new Employee(); |
| InsertObjectQuery query = new InsertObjectQuery(obj); |
| getAbstractSession().beginTransaction(); |
| getSession().executeQuery(query); |
| getAbstractSession().rollbackTransaction(); |
| System.gc(); |
| } |
| System.gc(); |
| } |
| |
| @Override |
| public void verify() { |
| // Force full GC. |
| for (int loops = 0; loops < 10; loops++) { |
| // The jdk1.2.0 on the Testing machine treats the weak reference as a softweak reference so we must waste memory |
| Vector vector = new Vector(50000); |
| for (int i = 0; i < 50000; i++) { |
| vector.add(new java.math.BigDecimal(i)); |
| } |
| |
| // Force garbage collection, which should clear the cache. |
| System.gc(); |
| System.runFinalization(); |
| } |
| // Check to see if maximum size was maintained. The maximum size is identityMapSize + 2, because System.gc() |
| //inside the for block does not garbage collect the object just inserted, also in put(CacheKey) method of WeakIdentityMap |
| //it checks if (getCleanupCount() > getMaxSize()) instead of =, which adds one more. |
| int maxSize = identityMapSize + 2; |
| if (getIdentityMap().getSize() > maxSize) { |
| throw new TestErrorException("Weak identity map " + getIdentityMap() + " contains " + |
| getIdentityMap().getSize() + " objects. " + |
| "The specified maximum size for this cache was " + maxSize + "."); |
| } |
| // Check that all the CacheReferences (WeakCacheReferences) are null, since |
| // they all should have been garbage collected. |
| Map<Object, CacheKey> cache = getIdentityMap().getCacheKeys(); |
| for (Iterator<CacheKey> iterator = cache.values().iterator(); iterator.hasNext(); ) { |
| CacheKey key = iterator.next(); |
| if (key.getObject() != null) { |
| throw new TestErrorException("A WeakCacheKey with a non-empty WeakReference was found. The garbage collection did not clear the cache as expected."); |
| } |
| } |
| } |
| |
| |
| } |