首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展ByteBuffer类

扩展ByteBuffer类
EN

Stack Overflow用户
提问于 2009-03-08 22:34:51
回答 7查看 7.8K关注 0票数 17

有没有办法创建扩展ByteBuffer类的类?

来自ByteBuffer的一些抽象方法是包私有的,如果我创建包java.nio,就会抛出安全异常。

我想这样做是出于性能原因--例如,getInt有大约10个方法调用,以及相当多的if。即使保留所有检查,只保留方法调用,删除大/小字节顺序检查,但我创建的测试表明,它可以快4倍左右。

EN

回答 7

Stack Overflow用户

发布于 2011-05-29 18:26:02

你不能扩展ByteBuffer,感谢上帝。

您不能扩展b/c,没有受保护的c-tor。为什么要谢天谢地呢?好吧,只有2个真正的子类确保了JVM可以大量优化任何涉及ByteBuffer的代码。

最后,如果你需要真正的扩展这个类,编辑字节代码,只需要给DirectByteBuffer (和DirectByteBufferR)添加受保护的属性c-tor和公共属性即可。扩展HeapBuffer没有任何作用,因为您无论如何都可以访问底层数组

使用-Xbootclasspath/p并在其中添加您自己的类,在您需要的包中扩展(在java.nio之外)。这就是它是如何做到的。

另一种方法是在address()之后使用sun.misc.Unsafe并通过直接访问内存来做任何你需要的事情。

我想这么做是出于性能原因--例如,getInt有大约10次方法调用,还有相当多的if。即使保留了所有检查,只有方法调用是内联的,删除了大/小字节顺序检查,但我创建的测试表明它可以快4倍左右。

现在最好的部分是,使用gdb并检查真正生成的机器码,您会惊讶地发现有多少检查将被删除。

我无法想象为什么一个人会想要扩展这些类。它们的存在是为了提供良好的性能,而不仅仅是OO多态执行。

编辑:

如何声明任何类并绕过Java验证器

Unsafe: Unsafe有两个绕过验证器的方法,如果你有一个扩展ByteBuffer的类,你可以直接调用它们中的任何一个。你需要一些受黑客攻击的ByteBuffer版本(但这非常容易),它具有公共访问权和受保护的c-tor,仅供编译器使用。方法如下。你可以在你自己承担风险的情况下使用它们。在你像这样声明类之后,你甚至可以使用new关键字(只要有合适的c-tor)

代码语言:javascript
复制
public native Class defineClass(String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain);    
public native Class defineClass(String name, byte[] b, int off, int len);
票数 15
EN

Stack Overflow用户

发布于 2009-03-08 23:04:07

您可以通过使用反射来忽略保护级别,但这在很大程度上违背了性能目标。

您不能在java.nio包中创建类-这样做(并以任何方式分发结果)违反了Sun许可,理论上可能会给您带来法律上的麻烦。

我不认为有一种方法可以做你想做的事情,而不是原生的--但我也怀疑你正在屈从于过早优化的诱惑。假设您的测试是正确的(微基准测试通常是不正确的):您确定对ByteBuffer的访问将成为实际应用程序中的性能瓶颈吗?当你的应用程序只在ByteBuffer.get()上花费了5%的时间和95%的时间来处理它获取的数据时,它是否能快4倍是不重要的。

为了性能(可能纯粹是理论上的)而想绕过所有检查听起来不是一个好主意。性能调优的基本原则是“首先让它正确工作,然后让它更快地工作”。

编辑:如果正如评论中所说,应用程序确实在ByteBuffer方法上花费了20-40%的时间,并且测试是正确的,这意味着15-30%的加速潜力-显著,但我不值得开始使用或扰乱API源。我会先尝试穷尽所有其他选项:

  • 您是否在使用-server VM?
  • 是否可以对应用程序进行修改,以减少对ByteBuffer的调用,而不是尝试加快调用的速度?
  • 使用探查器查看调用来自何处-可能有些是直接缓存算法可以修改,或者您可以使用某种缓存
票数 10
EN

Stack Overflow用户

发布于 2009-03-08 23:03:07

ByteBuffer是抽象的,所以,是的,你可以扩展它...但我认为您想要做的是扩展实际实例化的类,而您可能无法做到这一点。也可能是被实例化的特定方法覆盖了该方法,使其比ByteBuffer中的方法更有效。

我还想说,关于所有这些都是必需的,你可能大体上是错的--可能不是为了你正在测试的东西,但可能代码存在是有原因的(可能在其他平台上)。

如果你确实相信你是对的,打开一个bug,看看他们会怎么说。

如果想要添加到nio包中,可以在调用Java时尝试设置引导类路径。它应该让你把你的类放在rt.jar类之前。输入Xbootclasspath查看如何执行此操作,您需要使用-Xbootclasspath/p开关。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/624458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档