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

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

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

为什么Java包含这个类?


当前回答

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

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

其他回答

有趣的是,我甚至从未听说过这个类(这可能是一件好事,真的)。

我想到的一件事是使用Unsafe#setMemory将包含敏感信息的缓冲区归零(密码、密钥等)。您甚至可以对“不可变”对象的字段执行此操作(然后,我再次假设普通的反射也可以在这里执行此操作)。但我不是安全专家,所以对此持保留态度。

使用它来有效地访问和分配大量的内存,例如在您自己的体素引擎中!(例如《我的世界》风格的游戏。)

In my experience, the JVM is often unable to eliminate bounds-checking in place you truly need it. For example, if you're iterating over a large array, but the actual memory access is tucked underneath a non-virtual* method call in the loop, the JVM may still perform a bounds check with each array access, rather than once just before the loop. Thus, for potentially large performance gains, you can eliminate JVM bounds-checking inside the loop via a method which employs sun.misc.Unsafe to access the memory directly, making sure to do any bounds-checking yourself at the correct places. (You are gonna bounds check at some level, right?) *by non-virtual, I mean the JVM shouldn't have to dynamically resolve whatever your particular method is, because you've correctly guaranteed that class/method/instance are some combination of static/final/what-have-you.

对于我自己开发的体素引擎来说,这在块生成和序列化期间(在我同时读取/写入整个数组的低位置)带来了显著的性能提升。结果可能会有所不同,但如果缺乏界限消除是您的问题,那么这将解决它。

There are some potentially major problems with this: specifically, when you provide the ability to access memory without bounds-checking to clients of your interface, they will probably abuse it. (Don't forget that hackers can also be clients of your interface... especially in the case of a voxel engine written in Java.) Thus, you should either design your interface in a way such that memory access cannot be abused, or you should be extremely careful to validate user-data before it can ever, ever mingle with your dangerous interface. Considering the catastrophic things a hacker can do with unchecked memory access, it's probably best to take both approaches.

类不安全 用于执行低级、不安全操作的方法的集合。虽然类和所有方法都是公共的,但该类的使用是有限的,因为只有可信代码才能获得它的实例。

它的一种用法是在java.util.concurrent.atomic类中:

AtomicIntegerArray AtomicLongArray

对象的可用性似乎低于Java代码通常允许的级别。如果您正在编写一个高级应用程序,那么JVM将内存处理和其他操作从代码级别抽象出来,因此更容易编程。通过使用不安全库,您可以有效地完成通常由您完成的低级操作。

正如woliveirajr所述,“random()”使用Unsafe来播种,就像许多其他操作将使用Unsafe中包含的allocateMemory()函数一样。

作为程序员,你可能永远不需要这个库,但严格控制底层元素确实很方便(这就是为什么在主要产品中仍然有汇编代码和(在较小程度上)C代码的原因)

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