This is an automated email from the ASF dual-hosted git repository. yangjie01 pushed a commit to branch uniffle-144 in repository https://gitbox.apache.org/repos/asf/incubator-uniffle.git
commit 89db9b2ab21f5d909a9faf035b89e45b31713382 Author: yangjie01 <[email protected]> AuthorDate: Tue Sep 6 17:58:02 2022 +0800 fix --- .../org/apache/uniffle/common/RssShuffleUtils.java | 14 +++------- .../apache/uniffle/common/RssShuffleUtilsTest.java | 32 ++++++++++++++++++++-- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/common/src/main/java/org/apache/uniffle/common/RssShuffleUtils.java b/common/src/main/java/org/apache/uniffle/common/RssShuffleUtils.java index 58db058e..0ad71ae2 100644 --- a/common/src/main/java/org/apache/uniffle/common/RssShuffleUtils.java +++ b/common/src/main/java/org/apache/uniffle/common/RssShuffleUtils.java @@ -17,10 +17,10 @@ package org.apache.uniffle.common; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.nio.ByteBuffer; +import sun.nio.ch.DirectBuffer; + import com.google.common.base.Preconditions; import net.jpountz.lz4.LZ4Compressor; import net.jpountz.lz4.LZ4Factory; @@ -73,15 +73,9 @@ public class RssShuffleUtils { * */ public static void destroyDirectByteBuffer(ByteBuffer toBeDestroyed) - throws IllegalArgumentException, IllegalAccessException, - InvocationTargetException, SecurityException, NoSuchMethodException { + throws IllegalArgumentException, SecurityException { Preconditions.checkArgument(toBeDestroyed.isDirect(), "toBeDestroyed isn't direct!"); - Method cleanerMethod = toBeDestroyed.getClass().getMethod("cleaner"); - cleanerMethod.setAccessible(true); - Object cleaner = cleanerMethod.invoke(toBeDestroyed); - Method cleanMethod = cleaner.getClass().getMethod("clean"); - cleanMethod.setAccessible(true); - cleanMethod.invoke(cleaner); + ((DirectBuffer)toBeDestroyed).cleaner().clean(); } } diff --git a/common/src/test/java/org/apache/uniffle/common/RssShuffleUtilsTest.java b/common/src/test/java/org/apache/uniffle/common/RssShuffleUtilsTest.java index 1dd51ebf..c531834f 100644 --- a/common/src/test/java/org/apache/uniffle/common/RssShuffleUtilsTest.java +++ b/common/src/test/java/org/apache/uniffle/common/RssShuffleUtilsTest.java @@ -17,15 +17,19 @@ package org.apache.uniffle.common; +import java.lang.reflect.Field; +import java.nio.Buffer; import java.nio.ByteBuffer; +import sun.misc.Unsafe; + import org.apache.commons.lang3.RandomUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; public class RssShuffleUtilsTest { @@ -57,9 +61,19 @@ public class RssShuffleUtilsTest { byteBuffer.put(b); } byteBuffer.flip(); + + // Get valid native pointer through `address` in `DirectByteBuffer` + Unsafe unsafe = getUnsafe(); + long addressInByteBuffer = address(byteBuffer); + long originalAddress = unsafe.getAddress(addressInByteBuffer); + RssShuffleUtils.destroyDirectByteBuffer(byteBuffer); + // The memory may not be released fast enough. - Thread.sleep(200); + // If native pointer changes, `address` in `DirectByteBuffer` is invalid + while (unsafe.getAddress(addressInByteBuffer) == originalAddress) { + Thread.sleep(200); + } boolean same = true; byte[] read = new byte[size]; byteBuffer.get(read); @@ -69,6 +83,18 @@ public class RssShuffleUtilsTest { break; } } - assertTrue(!same); + assertFalse(same); + } + + private Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException { + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + return (sun.misc.Unsafe) unsafeField.get(null); + } + + private long address(ByteBuffer buffer) throws NoSuchFieldException, IllegalAccessException { + Field addressField = Buffer.class.getDeclaredField("address"); + addressField.setAccessible(true); + return (long) addressField.get(buffer); } }
