前几天我偶然发现了一个不安全的包装,它的功能让我感到惊讶。

当然,这个类是没有记录的,但是我想知道是否有一个很好的理由使用它。可能会出现哪些需要使用它的场景?如何在现实场景中使用它?

此外,如果您确实需要它,这难道不表明您的设计可能存在问题吗?

为什么Java包含这个类?


当前回答

堆外集合对于分配大量内存并在使用后立即释放内存而不受GC干扰可能很有用。我基于sun.misc.Unsafe编写了一个用于处理堆外数组/列表的库。

其他回答

如果您需要替换当前使用它的某个类所提供的功能,则需要使用它。

这可以是自定义/更快/更紧凑的序列化/反序列化,一个更快/更大的缓冲区/可调整大小的ByteBuffer版本,或者添加一个原子变量,例如当前不支持的。

我曾经用它来处理所有这些问题。

我们使用Unsafe实现了数组、HashMaps、TreeMaps等大型集合。为了避免/最小化碎片,我们使用dlmalloc over unsafe的概念实现内存分配器。这帮助我们获得了并发性方面的性能。

通过在一些代码搜索引擎中运行搜索,我得到了以下示例:

Java对象符号——使用它来进行更有效的数组处理,引用javadoc

类来获取对{@link Unsafe}对象的访问。{@link安全} 为了允许对数组进行有效的CAS操作,*是必需的。注意 {@link java.util.concurrent中的版本。原子},例如{@link java.util.concurrent.atomic。AtomicLongArray},需要额外的内存排序 这些保证在这些算法中通常是不需要的 在大多数处理器上都很昂贵。

SoyLatte - java 6 for osx javadoc excerpt

/** sun.misc的基类基于静态的不安全的FieldAccessors 字段。据观察,只有9种类型的 从反射代码的角度看字段:八个原语 类型和对象。使用不安全类而不是生成类 字节码节省内存和加载时间 动态生成的FieldAccessors。* /

SpikeSource

/* 通过线路发送的FinalFields ..如何解编和重新创建对象上 接收方?我们不想调用构造函数,因为它将为 最后一个字段。我们必须重新创建与发送端完全相同的最终字段。 太阳,杂项,不安全为我们做了这些。 * /

还有很多其他的例子,只要按上面的链接…

它使用的一个例子是random方法,该方法调用不安全的方法来更改种子。

这个网站也有它的一些用途。

基于对使用eclipse进行引用跟踪的Java 1.6.12库的简要分析,似乎Unsafe的每个有用功能都以有用的方式公开了。

CAS操作通过Atomic*类公开。 内存操作函数通过DirectByteBuffer公开 同步指令(park,unpark)通过AbstractQueuedSynchronizer公开,而AbstractQueuedSynchronizer又由Lock实现使用。