memoryleaktestcase.java
来自「这是一个有关common beanutils 的源码」· Java 代码 · 共 575 行 · 第 1/2 页
JAVA
575 行
/*
* 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.commons.beanutils.memoryleaktests;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Locale;
import java.util.StringTokenizer;
import junit.framework.TestCase;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.MappedPropertyDescriptor;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.WrapDynaBean;
import org.apache.commons.beanutils.WrapDynaClass;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.locale.LocaleBeanUtilsBean;
import org.apache.commons.beanutils.locale.LocaleConvertUtils;
import org.apache.commons.beanutils.locale.converters.IntegerLocaleConverter;
/**
* Test BeanUtils memory leaks.
*
* See https://issues.apache.org/jira/browse/BEANUTILS-291
*
* @author Clebert Suconic
*/
public class MemoryLeakTestCase extends TestCase {
/**
* Tests that PropertyUtilsBean's descriptorsCache doesn't cause a memory leak.
*/
public void testPropertyUtilsBean_descriptorsCache_memoryLeak() throws Exception {
if (isPre15JVM()) {
return;
}
// Clear All BeanUtils caches before the test
clearAllBeanUtilsCaches();
String className = "org.apache.commons.beanutils.memoryleaktests.pojotests.SomePojo";
// The classLoader will go away only when these following variables are released
ClassLoader loader = newClassLoader();
Class beanClass = loader.loadClass(className);
Object bean = beanClass.newInstance();
// -----------------------------------------------------------------------------
WeakReference someRef = new WeakReference(loader);
// Sanity checks only
assertNotNull("ClassLoader is null", loader);
assertNotNull("BeanClass is null", beanClass);
assertNotSame("ClassLoaders should be different..", getClass().getClassLoader(), beanClass.getClassLoader());
assertSame("BeanClass ClassLoader incorrect", beanClass.getClassLoader(), loader);
// if you comment the following line, the testcase will work, and the ClassLoader will be released.
// That proves that nothing is wrong with the test, and PropertyUtils is holding a reference
assertEquals("initialValue", PropertyUtils.getProperty(bean, "name"));
// this should make the reference go away.
loader = null;
beanClass = null;
bean = null;
forceGarbageCollection(); /* Try to force the garbage collector to run by filling up memory */
if (someRef.get() != null) {
profilerLeakReport("PropertyUtilsBean descriptorsCache", className);
}
// if everything is fine, this will be null
assertNull("PropertyUtilsBean is holding a reference to the classLoader", someRef.get());
// Clear All BeanUtils caches after the test
clearAllBeanUtilsCaches();
}
/**
* Tests that PropertyUtilsBean's mappedDescriptorsCache doesn't cause a memory leak.
*/
public void testPropertyUtilsBean_mappedDescriptorsCache_memoryLeak() throws Exception {
if (isPre15JVM()) {
return;
}
// Clear All BeanUtils caches before the test
clearAllBeanUtilsCaches();
String className = "org.apache.commons.beanutils.memoryleaktests.pojotests.SomeMappedPojo";
// The classLoader will go away only when these following variables are released
ClassLoader loader = newClassLoader();
Class beanClass = loader.loadClass(className);
Object bean = beanClass.newInstance();
// -----------------------------------------------------------------------------
WeakReference someRef = new WeakReference(loader);
// Sanity checks only
assertNotNull("ClassLoader is null", loader);
assertNotNull("BeanClass is null", beanClass);
assertNotSame("ClassLoaders should be different..", getClass().getClassLoader(), beanClass.getClassLoader());
assertSame("BeanClass ClassLoader incorrect", beanClass.getClassLoader(), loader);
// if you comment the following three lines, the testcase will work, and the ClassLoader will be released.
// That proves that nothing is wrong with the test, and PropertyUtils is holding a reference
assertEquals("Second Value", PropertyUtils.getProperty(bean, "mappedProperty(Second Key)"));
PropertyUtils.setProperty(bean, "mappedProperty(Second Key)", "New Second Value");
assertEquals("New Second Value", PropertyUtils.getProperty(bean, "mappedProperty(Second Key)"));
// this should make the reference go away.
loader = null;
beanClass = null;
bean = null;
// PropertyUtilsBean uses the MethodUtils's method cache for mapped properties.
// Uncomment the following line to check this is not just a repeat of that memory leak.
// MethodUtils.clearCache();
forceGarbageCollection(); /* Try to force the garbage collector to run by filling up memory */
if (someRef.get() != null) {
profilerLeakReport("PropertyUtilsBean mappedDescriptorsCache", className);
}
// if everything is fine, this will be null
assertNull("PropertyUtilsBean is holding a reference to the classLoader", someRef.get());
// Clear All BeanUtils caches after the test
clearAllBeanUtilsCaches();
}
/**
* Tests that MappedPropertyDescriptor can re-create the Method reference after it
* has been garbage collected.
*/
public void testMappedPropertyDescriptor_MappedMethodReference1() throws Exception {
// Clear All BeanUtils caches before the test
clearAllBeanUtilsCaches();
String className = "org.apache.commons.beanutils.memoryleaktests.pojotests.SomeMappedPojo";
ClassLoader loader = newClassLoader();
Class beanClass = loader.loadClass(className);
Object bean = beanClass.newInstance();
// -----------------------------------------------------------------------------
// Sanity checks only
assertNotNull("ClassLoader is null", loader);
assertNotNull("BeanClass is null", beanClass);
assertNotSame("ClassLoaders should be different..", getClass().getClassLoader(), beanClass.getClassLoader());
assertSame("BeanClass ClassLoader incorrect", beanClass.getClassLoader(), loader);
MappedPropertyDescriptor descriptor = new MappedPropertyDescriptor("mappedProperty", beanClass);
assertNotNull("1-Read Method null", descriptor.getMappedReadMethod());
assertNotNull("1-Write Method null", descriptor.getMappedWriteMethod());
assertEquals("1-Read Method name", "getMappedProperty", descriptor.getMappedReadMethod().getName());
assertEquals("1-Read Write name", "setMappedProperty", descriptor.getMappedWriteMethod().getName());
forceGarbageCollection(); /* Try to force the garbage collector to run by filling up memory */
// The aim of this test is to check the functinality in MappedPropertyDescriptor which
// re-creates the Method references after they have been garbage collected. However theres no
// way of knowing the method references were garbage collected and that code was run, except by
// un-commeting the System.out statement in MappedPropertyDescriptor's MappedMethodReference's
// get() method.
assertNotNull("1-Read Method null", descriptor.getMappedReadMethod());
assertNotNull("1-Write Method null", descriptor.getMappedWriteMethod());
assertEquals("1-Read Method name", "getMappedProperty", descriptor.getMappedReadMethod().getName());
assertEquals("1-Read Write name", "setMappedProperty", descriptor.getMappedWriteMethod().getName());
// Clear All BeanUtils caches after the test
clearAllBeanUtilsCaches();
}
/**
* Tests that MappedPropertyDescriptor can re-create the Method reference after it
* has been garbage collected.
*/
public void testMappedPropertyDescriptor_MappedMethodReference2() throws Exception {
// Clear All BeanUtils caches before the test
clearAllBeanUtilsCaches();
String className = "org.apache.commons.beanutils.memoryleaktests.pojotests.SomeMappedPojo";
ClassLoader loader = newClassLoader();
Class beanClass = loader.loadClass(className);
Object bean = beanClass.newInstance();
// -----------------------------------------------------------------------------
// Sanity checks only
assertNotNull("ClassLoader is null", loader);
assertNotNull("BeanClass is null", beanClass);
assertNotSame("ClassLoaders should be different..", getClass().getClassLoader(), beanClass.getClassLoader());
assertSame("BeanClass ClassLoader incorrect", beanClass.getClassLoader(), loader);
MappedPropertyDescriptor descriptor = new MappedPropertyDescriptor("mappedProperty", beanClass);
assertNotNull("1-Read Method null", descriptor.getMappedReadMethod());
assertNotNull("1-Write Method null", descriptor.getMappedWriteMethod());
assertEquals("1-Read Method name", "getMappedProperty", descriptor.getMappedReadMethod().getName());
assertEquals("1-Read Write name", "setMappedProperty", descriptor.getMappedWriteMethod().getName());
// this should make the reference go away.
loader = null;
beanClass = null;
bean = null;
forceGarbageCollection(); /* Try to force the garbage collector to run by filling up memory */
// The aim of this test is to check the functinality in MappedPropertyDescriptor which
// re-creates the Method references after they have been garbage collected. However theres no
// way of knowing the method references were garbage collected and that code was run, except by
// un-commeting the System.out statement in MappedPropertyDescriptor's MappedMethodReference's
// get() method.
assertNotNull("1-Read Method null", descriptor.getMappedReadMethod());
assertNotNull("1-Write Method null", descriptor.getMappedWriteMethod());
assertEquals("1-Read Method name", "getMappedProperty", descriptor.getMappedReadMethod().getName());
assertEquals("1-Read Write name", "setMappedProperty", descriptor.getMappedWriteMethod().getName());
// Clear All BeanUtils caches after the test
clearAllBeanUtilsCaches();
}
/**
* Tests that MethodUtils's cache doesn't cause a memory leak.
*/
public void testMethodUtils_cache_memoryLeak() throws Exception {
// Clear All BeanUtils caches before the test
clearAllBeanUtilsCaches();
String className = "org.apache.commons.beanutils.memoryleaktests.pojotests.SomePojo";
// The classLoader will go away only when these following variables are released
ClassLoader loader = newClassLoader();
Class beanClass = loader.loadClass(className);
Object bean = beanClass.newInstance();
// -----------------------------------------------------------------------------
WeakReference someRef = new WeakReference(loader);
// Sanity checks only
assertNotNull("ClassLoader is null", loader);
assertNotNull("BeanClass is null", beanClass);
assertNotSame("ClassLoaders should be different..", getClass().getClassLoader(), beanClass.getClassLoader());
assertSame("BeanClass ClassLoader incorrect", beanClass.getClassLoader(), loader);
// if you comment the following line, the testcase will work, and the ClassLoader will be released.
// That proves that nothing is wrong with the test, and MethodUtils is holding a reference
assertEquals("initialValue", MethodUtils.invokeExactMethod(bean, "getName", new Object[0]));
// this should make the reference go away.
loader = null;
beanClass = null;
bean = null;
forceGarbageCollection(); /* Try to force the garbage collector to run by filling up memory */
if (someRef.get() != null) {
profilerLeakReport("MethodUtils cache", className);
}
// if everything is fine, this will be null
assertNull("MethodUtils is holding a reference to the classLoader", someRef.get());
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?