java - Java 可以写入/读取已释放的堆外内存吗?

标签 java unsafe

这确实让我感到惊讶,我正在玩 Java Unsafe。基本上我正在测试的是

Allocate unsafe memory -> free the memory -> Write to the freed memory

我期望在访问已释放的内存时看到某种段错误,但令人惊讶的是,没有引发任何错误/异常。

我的代码是:

protected static final Unsafe UNSAFE;
static {
    try {
        Field field = Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(true);
        UNSAFE = (Unsafe) field.get(null);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
@Test
public void test() {
    long ptr = UNSAFE.allocateMemory(1000);
    UNSAFE.freeMemory(ptr);
    UNSAFE.putOrderedLong(null, ptr, 100L);
}

我的问题是,如果是这样,为什么我们需要 Unsafe 中的 freeMemory() 函数?它的真正用途是什么?

最佳答案

只有当您读取未分配页面的地址或写入只读或未分配页面的内存时,您才会收到信号。

当您分配小的内存区域时,它会从 native 内存池中获取它,该内存池在释放时通常不会释放回操作系统。

如果您释放内存然后再分配它,那么该内存可以用于不同的目的。继续使用旧地址可能会导致损坏。

关于java - Java 可以写入/读取已释放的堆外内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52885353/

相关文章:

java - SVN SSL 握手失败 : SSL error: bad packet length

java - 启用 GPS 时启动我的 Android 应用程序强制关闭

c# - 在不装箱的情况下将字节数组复制到通用类型

java - Java 中 unsafe.allocateMemory 返回什么

java - 在cygwin中运行和编译java代码

java - 一起滚动 ListView

java - Spring组件扫描

c# - 如何使用关键字 fixed 在 C# 中固定整个数组

c# - 遵循不安全的数组索引是否有任何性能差异?

pointers - 为什么通过原始指针修改可变引用的值不会违反 Rust 的别名规则?