From 84e5f0e32314635cfb70b559d93ad3533c06d0ef Mon Sep 17 00:00:00 2001 From: Elmi Ahmadov Date: Fri, 18 Jan 2019 15:21:34 +0100 Subject: [PATCH 1/2] Replace ArrayList `.equals()` method with `==` to compare the objects MemoryManagerReferenceHandler.v8HandleDisposed method is already implemented with Iterator to compare the object using `==` instead of `.equals`. Therefore, MemoryManagerReferenceHandler.v8HandleDisposed can be used rather than ArrayList.remove to remove object from references array. Fix #444 --- .../java/com/eclipsesource/v8/utils/MemoryManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/eclipsesource/v8/utils/MemoryManager.java b/src/main/java/com/eclipsesource/v8/utils/MemoryManager.java index 7f236ae56..26bae1fc6 100644 --- a/src/main/java/com/eclipsesource/v8/utils/MemoryManager.java +++ b/src/main/java/com/eclipsesource/v8/utils/MemoryManager.java @@ -31,7 +31,7 @@ public class MemoryManager { private MemoryManagerReferenceHandler memoryManagerReferenceHandler; private V8 v8; private ArrayList references = new ArrayList(); - private boolean releasing = false; + private boolean releasing = false; private boolean released = false; /** @@ -73,7 +73,7 @@ public int getObjectReferenceCount() { public void persist(final V8Value object) { v8.getLocker().checkThread(); checkReleased(); - references.remove(object); + memoryManagerReferenceHandler.v8HandleDisposed(object); } /** @@ -92,7 +92,7 @@ public boolean isReleased() { */ public void release() { v8.getLocker().checkThread(); - if (released) { + if (isReleased()) { return; } releasing = true; @@ -109,7 +109,7 @@ public void release() { } private void checkReleased() { - if (released) { + if (isReleased()) { throw new IllegalStateException("Memory manager released"); } } From 2b5c9977251800c5d41aa388c3e13979bae99ffe Mon Sep 17 00:00:00 2001 From: Elmi Ahmadov Date: Mon, 21 Jan 2019 13:06:56 +0100 Subject: [PATCH 2/2] Add unit tests to MemoryManagerTest Unit tests verify the following cases: * Persisted object decrease MemoryManager object reference count * Duplicated object is not managed by MemoryManager when persisted --- .../eclipsesource/v8/utils/MemoryManager.java | 4 +-- .../v8/utils/MemoryManagerTest.java | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/eclipsesource/v8/utils/MemoryManager.java b/src/main/java/com/eclipsesource/v8/utils/MemoryManager.java index 26bae1fc6..38c63b08f 100644 --- a/src/main/java/com/eclipsesource/v8/utils/MemoryManager.java +++ b/src/main/java/com/eclipsesource/v8/utils/MemoryManager.java @@ -92,7 +92,7 @@ public boolean isReleased() { */ public void release() { v8.getLocker().checkThread(); - if (isReleased()) { + if (released) { return; } releasing = true; @@ -109,7 +109,7 @@ public void release() { } private void checkReleased() { - if (isReleased()) { + if (released) { throw new IllegalStateException("Memory manager released"); } } diff --git a/src/test/java/com/eclipsesource/v8/utils/MemoryManagerTest.java b/src/test/java/com/eclipsesource/v8/utils/MemoryManagerTest.java index 61cc83bfd..59f9213cb 100644 --- a/src/test/java/com/eclipsesource/v8/utils/MemoryManagerTest.java +++ b/src/test/java/com/eclipsesource/v8/utils/MemoryManagerTest.java @@ -315,4 +315,32 @@ public void v8HandleCreated(final V8Value object) { assertTrue(memoryManager.isReleased()); } + @Test + public void testPersistedObjectAffectReferenceCount() { + MemoryManager memoryManager = new MemoryManager(v8); + V8Object object = new V8Object(v8); + + assertEquals(1, memoryManager.getObjectReferenceCount()); + memoryManager.persist(object); + assertEquals(0, memoryManager.getObjectReferenceCount()); + + memoryManager.release(); + object.close(); + } + + @Test + public void testPersistDuplicatedObject() { + MemoryManager memoryManager = new MemoryManager(v8); + V8Object object1 = new V8Object(v8); + V8Object object2 = object1.twin(); + + memoryManager.persist(object2); + memoryManager.release(); + + assertTrue(object1.isReleased()); + assertFalse(object2.isReleased()); + object1.close(); + object2.close(); + } + }