[Jiemamy-notify:2397] commit [3397] [CORE-105] ReferenceResolverImpl 保持するモデルのマッピングを弱参照に変更。

Zurück zum Archiv-Index

svnno****@sourc***** svnno****@sourc*****
2009年 5月 9日 (土) 14:17:13 JST


Revision: 3397
          http://svn.sourceforge.jp/view?root=jiemamy&view=rev&rev=3397
Author:   daisuke_m
Date:     2009-05-09 14:17:13 +0900 (Sat, 09 May 2009)

Log Message:
-----------
[CORE-105] ReferenceResolverImpl 保持するモデルのマッピングを弱参照に変更。

Modified Paths:
--------------
    artemis/trunk/jiemamy-core/pom.xml
    artemis/trunk/jiemamy-core/src/main/java/org/jiemamy/internal/ReferenceResolverImpl.java
    artemis/trunk/jiemamy-core/src/test/java/org/jiemamy/internal/ReferenceResolverImplTest.java
    leto/jiemamy-test-helper/trunk/pom.xml

Added Paths:
-----------
    leto/jiemamy-test-helper/trunk/src/main/java/org/jiemamy/internal/test/JiemamyAssert.java
    leto/jiemamy-test-helper/trunk/src/test/java/org/
    leto/jiemamy-test-helper/trunk/src/test/java/org/jiemamy/
    leto/jiemamy-test-helper/trunk/src/test/java/org/jiemamy/internal/
    leto/jiemamy-test-helper/trunk/src/test/java/org/jiemamy/internal/test/
    leto/jiemamy-test-helper/trunk/src/test/java/org/jiemamy/internal/test/JiemamyAssertTest.java


-------------- next part --------------
Modified: artemis/trunk/jiemamy-core/pom.xml
===================================================================
--- artemis/trunk/jiemamy-core/pom.xml	2009-05-09 03:19:34 UTC (rev 3396)
+++ artemis/trunk/jiemamy-core/pom.xml	2009-05-09 05:17:13 UTC (rev 3397)
@@ -84,7 +84,7 @@
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>jiemamy-test-helper</artifactId>
-      <version>0.0.1</version>
+      <version>0.2.1-SNAPSHOT</version>
       <scope>test</scope>
     </dependency>
     <dependency>

Modified: artemis/trunk/jiemamy-core/src/main/java/org/jiemamy/internal/ReferenceResolverImpl.java
===================================================================
--- artemis/trunk/jiemamy-core/src/main/java/org/jiemamy/internal/ReferenceResolverImpl.java	2009-05-09 03:19:34 UTC (rev 3396)
+++ artemis/trunk/jiemamy-core/src/main/java/org/jiemamy/internal/ReferenceResolverImpl.java	2009-05-09 05:17:13 UTC (rev 3397)
@@ -19,13 +19,13 @@
 package org.jiemamy.internal;
 
 import java.lang.reflect.InvocationTargetException;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.UUID;
 import java.util.Map.Entry;
 
 import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.collections15.map.ReferenceMap;
 import org.apache.commons.lang.Validate;
 import org.apache.commons.lang.builder.ToStringBuilder;
 import org.slf4j.Logger;
@@ -35,7 +35,6 @@
 import org.jiemamy.ReferenceResolver;
 import org.jiemamy.model.ElementReference;
 import org.jiemamy.model.JiemamyElement;
-import org.jiemamy.model.RootModel;
 import org.jiemamy.utils.LogMarker;
 
 /**
@@ -50,11 +49,12 @@
 	/**
 	 * {@link JiemamyElement}のidと{@link JiemamyElement}の実体をマッピングする{@link Map}
 	 * 
-	 * <p>FIXME マッピングが登録されることはあっても、リリースされることがない。
-	 * モデルを大量に生成した場合、{@link RootModel}からたどることのないモデルであっても、このMapが参照を握ってヒープが溢れる。
+	 * <p>マッピングが登録されることはあっても、意図的にリリースされることがない。通常のMapを使うと、
+	 * モデルを大量に生成した場合、GC対象になるべきモデルインスタンスであっても、このMapが参照を握ってヒープが溢れてしまう。
 	 * {@link ReferenceResolverImplTest#test00_メモリリークテスト()}及び CORE-105 を参照。<p>
 	 */
-	private static Map<UUID, JiemamyElement> elementMapping = new HashMap<UUID, JiemamyElement>();
+	private static Map<UUID, JiemamyElement> elementMapping =
+			new ReferenceMap<UUID, JiemamyElement>(ReferenceMap.HARD, ReferenceMap.WEAK);
 	
 
 	/**
@@ -110,10 +110,13 @@
 				}
 			}
 		} catch (IllegalAccessException e) {
+			// TODO 適切な例外処理
 			e.printStackTrace();
 		} catch (InvocationTargetException e) {
+			// TODO 適切な例外処理
 			e.printStackTrace();
 		} catch (NoSuchMethodException e) {
+			// TODO 適切な例外処理
 			e.printStackTrace();
 		}
 		return false;

Modified: artemis/trunk/jiemamy-core/src/test/java/org/jiemamy/internal/ReferenceResolverImplTest.java
===================================================================
--- artemis/trunk/jiemamy-core/src/test/java/org/jiemamy/internal/ReferenceResolverImplTest.java	2009-05-09 03:19:34 UTC (rev 3396)
+++ artemis/trunk/jiemamy-core/src/test/java/org/jiemamy/internal/ReferenceResolverImplTest.java	2009-05-09 05:17:13 UTC (rev 3397)
@@ -19,14 +19,14 @@
 package org.jiemamy.internal;
 
 import static org.hamcrest.CoreMatchers.is;
+import static org.jiemamy.internal.test.JiemamyAssert.assertGc;
 import static org.junit.Assert.assertThat;
 
+import java.lang.ref.WeakReference;
 import java.util.Stack;
 
-import org.apache.commons.lang.RandomStringUtils;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -34,6 +34,7 @@
 import org.jiemamy.EventBroker;
 import org.jiemamy.Jiemamy;
 import org.jiemamy.JiemamyFactory;
+import org.jiemamy.ReferenceResolver;
 import org.jiemamy.editcommand.Command;
 import org.jiemamy.internal.editcommand.AddAttributeCommand;
 import org.jiemamy.internal.editcommand.AddColumnToColumnRefListCommand;
@@ -44,6 +45,8 @@
 import org.jiemamy.model.RootModel;
 import org.jiemamy.model.attribute.ColumnModel;
 import org.jiemamy.model.attribute.constraint.PrimaryKey;
+import org.jiemamy.model.datatype.DomainModel;
+import org.jiemamy.model.datatype.DomainRef;
 import org.jiemamy.model.entity.TableModel;
 
 /**
@@ -102,15 +105,24 @@
 	 * @throws Exception 例外が発生した場合
 	 */
 	@Test
-	@Ignore
 	public void test00_メモリリークテスト() throws Exception {
-		for (int i = 0; i < 100000; i++) {
-			TableModel tableModel = factory.newModel(TableModel.class);
-			tableModel.setName(RandomStringUtils.randomAlphabetic(10));
-			ColumnModel columnModel = factory.newModel(ColumnModel.class);
-			columnModel.setName(RandomStringUtils.randomAlphabetic(10));
-			tableModel.getAttributes().add(columnModel);
-		}
+		// A. GCによって解放されないモデル(ここのローカル変数で強参照を持っている)
+		DomainModel domainModel1 = factory.newModel(DomainModel.class);
+		DomainRef domainRef1 = factory.newReference(domainModel1);
+		
+		// B. GCによって解放されるモデル(弱参照とUUIDによるモデル参照しか持っていない)
+		DomainModel domainModel2 = factory.newModel(DomainModel.class);
+		DomainRef domainRef2 = factory.newReference(domainModel2);
+		WeakReference<DomainModel> weakReference = new WeakReference<DomainModel>(domainModel2);
+		domainModel2 = null;
+		
+		// GCを発生させる。
+		assertGc(weakReference);
+		
+		// Aは解決でき、Bは解決できない。
+		ReferenceResolver referenceResolver = jiemamy.getReferenceResolver();
+		assertThat(referenceResolver.canResolve(domainRef1), is(true));
+		assertThat(referenceResolver.canResolve(domainRef2), is(false));
 	}
 	
 	/**

Modified: leto/jiemamy-test-helper/trunk/pom.xml
===================================================================
--- leto/jiemamy-test-helper/trunk/pom.xml	2009-05-09 03:19:34 UTC (rev 3396)
+++ leto/jiemamy-test-helper/trunk/pom.xml	2009-05-09 05:17:13 UTC (rev 3397)
@@ -6,7 +6,7 @@
   <groupId>org.jiemamy</groupId>
   <artifactId>jiemamy-test-helper</artifactId>
   <name>Jiemamy Test Helper</name>
-  <version>0.3.0-SNAPSHOT</version>
+  <version>0.2.1-SNAPSHOT</version>
   <url>http://report.jiemamy.org/jiemamy-test-helper</url>
   <issueManagement>
     <system>JIRA</system>
@@ -151,12 +151,12 @@
     <dependency>
       <groupId>org.jiemamy</groupId>
       <artifactId>jiemamy-spec-core</artifactId>
-      <version>0.3-SNAPSHOT</version>
+      <version>0.2</version>
     </dependency>
     <dependency>
       <groupId>org.jiemamy</groupId>
       <artifactId>jiemamy-spec-view</artifactId>
-      <version>0.3-SNAPSHOT</version>
+      <version>0.2</version>
     </dependency>
     <dependency>
       <groupId>org.jiemamy</groupId>

Added: leto/jiemamy-test-helper/trunk/src/main/java/org/jiemamy/internal/test/JiemamyAssert.java
===================================================================
--- leto/jiemamy-test-helper/trunk/src/main/java/org/jiemamy/internal/test/JiemamyAssert.java	                        (rev 0)
+++ leto/jiemamy-test-helper/trunk/src/main/java/org/jiemamy/internal/test/JiemamyAssert.java	2009-05-09 05:17:13 UTC (rev 3397)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2007-2009 Jiemamy Project and the Others.
+ * Created on 2009/05/09
+ *
+ * This file is part of Jiemamy.
+ *
+ * Licensed 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.jiemamy.internal.test;
+
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.util.LinkedList;
+
+/**
+ * TODO for daisuke
+ * 
+ * <p>cf. http://d.hatena.ne.jp/ashigeru/20080506/1210092877</p>
+ * 
+ * @author daisuke
+ */
+public class JiemamyAssert {
+	
+	private static final int ALLOCATE_SIZE = 65536;
+	
+
+	/**
+	 * GCを発生させ、指定した弱参照が解放されることを表明する。
+	 * 
+	 * @param ref 弱参照
+	 */
+	public static void assertGc(WeakReference<?> ref) {
+		SoftReference<LinkedList<int[]>> memoryEater1 = new SoftReference<LinkedList<int[]>>(new LinkedList<int[]>());
+		SoftReference<LinkedList<int[]>> memoryEater2 = new SoftReference<LinkedList<int[]>>(new LinkedList<int[]>());
+		
+		while (true) {
+			System.gc();
+			if (consumeMemory(memoryEater1)) {
+				break;
+			}
+			if (consumeMemory(memoryEater2)) {
+				break;
+			}
+		}
+		
+		if (ref.get() != null) {
+			throw new AssertionError();
+		}
+	}
+	
+	private static boolean consumeMemory(SoftReference<LinkedList<int[]>> eater) {
+		LinkedList<int[]> list = eater.get();
+		if (list == null) {
+			return true;
+		}
+		list.add(new int[ALLOCATE_SIZE]);
+		return false;
+	}
+	
+	private JiemamyAssert() {
+	}
+}


Property changes on: leto/jiemamy-test-helper/trunk/src/main/java/org/jiemamy/internal/test/JiemamyAssert.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: leto/jiemamy-test-helper/trunk/src/test/java/org/jiemamy/internal/test/JiemamyAssertTest.java
===================================================================
--- leto/jiemamy-test-helper/trunk/src/test/java/org/jiemamy/internal/test/JiemamyAssertTest.java	                        (rev 0)
+++ leto/jiemamy-test-helper/trunk/src/test/java/org/jiemamy/internal/test/JiemamyAssertTest.java	2009-05-09 05:17:13 UTC (rev 3397)
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2007-2009 Jiemamy Project and the Others.
+ * Created on 2009/05/09
+ *
+ * This file is part of Jiemamy.
+ *
+ * Licensed 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.jiemamy.internal.test;
+
+import static org.junit.Assert.fail;
+
+import java.lang.ref.WeakReference;
+
+import org.junit.Test;
+
+/**
+ * {@link JiemamyAssert}のテストクラス。
+ * 
+ * <p>cf. http://d.hatena.ne.jp/ashigeru/20080506/1210092877</p>
+ * 
+ * @author daisuke
+ */
+public class JiemamyAssertTest {
+	
+	/**
+	 * Test method for {@link JiemamyAssert#assertGc(java.lang.ref.WeakReference)}.
+	 */
+	@Test
+	public void testAssertGc() {
+		Object obj = new String("Hello, world!");
+		WeakReference<Object> ref = new WeakReference<Object>(obj);
+		
+		// keeps only weak references
+		obj = null;
+		
+		JiemamyAssert.assertGc(ref);
+	}
+	
+	/**
+	 * Test method for {@link JiemamyAssert#assertGc(java.lang.ref.WeakReference)}.
+	 */
+	@Test
+	public void testAssertGcLeak() {
+		Object obj = new String("Hello, world!");
+		WeakReference<Object> ref = new WeakReference<Object>(obj);
+		
+		// keeps strong references
+		// obj = null;
+		
+		try {
+			JiemamyAssert.assertGc(ref);
+			fail();
+		} catch (AssertionError e) {
+			// success
+		}
+	}
+	
+}


Property changes on: leto/jiemamy-test-helper/trunk/src/test/java/org/jiemamy/internal/test/JiemamyAssertTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain



Jiemamy-notify メーリングリストの案内
Zurück zum Archiv-Index