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