- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在某些情况下,需要一种高效的内存来存储大量对象。要在 Java 中做到这一点,您不得不使用几个原始数组(请参阅下面的原因)或一个大字节数组,这会产生一些 CPU 开销以进行转换。
例子:你有一个 class Point { float x; float y;
。现在您想将 N 个点存储在一个数组中,在 32 位 JVM 上,该数组至少需要 N * 8 个字节用于 float ,N * 4 个字节用于引用。所以至少有 1/3 是垃圾(这里不计算普通对象开销)。但是,如果您将其存储在两个 float 组中,一切都会很好。
我的问题:为什么 Java 不优化引用数组的内存使用?我的意思是为什么不像在 C++ 中那样直接将对象嵌入数组中?
例如将类 Point 标记为 final 应该足以让 JVM 看到 Point 类数据的最大长度。或者这是反对the specification的地方?此外,在处理大型 n 维矩阵等时,这将节省大量内存
更新:
我想知道 JVM 是否可以在理论上优化它(例如在幕后)以及在什么条件下 - 而不是我是否可以以某种方式强制 JVM。我认为结论的第二点是无法轻易完成的原因。
JVM 需要知道的结论:
Point p = arr[i]; p.setX(i)
但您不能通过 inlineArr[i] = new Point()
写入数组。或者 JVM 将不得不引入与“Java 方式”相反的复制语义。查看 aroth 的回答最佳答案
Java 不提供执行此操作的方法,因为它不是语言级别的选择。 C、C++ 等公开了执行此操作的方法,因为它们是系统级编程语言,您需要了解系统级功能并根据您使用的特定架构做出决策。
在 Java 中,您的目标是 JVM。 JVM 没有指定这是否允许(我假设这是真的;我没有彻底梳理 JLS 来证明我在这里)。这个想法是,当您编写 Java 代码时,您相信 JIT 会做出明智的决定。这就是引用类型可以折叠成数组等的地方。因此,这里的“Java 方式”是您无法指定它是否发生,但如果 JIT 可以进行优化并提高性能,它就可以而且应该这样做。
我不确定这个优化是否具体实现了,但我知道类似的是:例如,用 new
分配的对象在概念上是在“堆”上,但是如果 JVM注意到(通过一种称为逃逸分析的技术)对象是方法局部的,它可以在堆栈上甚至直接在 CPU 寄存器中分配对象的字段,完全消除“堆分配”开销而无需更改语言。
更新问题的更新
如果问题是“这完全可以做到”,我认为答案是肯定的。有一些极端情况(例如空指针),但您应该能够解决它们。对于空引用,JVM 可以说服自己永远不会有空元素,或者如前所述保留一个位 vector 。这两种技术都可能基于逃逸分析,表明数组引用永远不会离开方法,因为我可以看到,如果你尝试,例如,簿记会变得棘手。将其存储在对象字段中。
关于java - 理论上 'structs' 的数组在 Java 中是可行的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9387055/
只是要清楚我没有一个具体的例子,因为使用的方式 到目前为止,建议使用各种“如何”来实现适合我的需求,并且我还没有遇到关于锁的任何问题,但是在python中使用锁确实引发了以下问题 似乎调用lock.a
这是一个理论问题;作为一名计算机科学爱好者,我一直在思考这个问题,并且正在尝试理解可能(或正在)用于解决这个问题的逻辑和方法。 问题:假设您有一个数字空间可以在其中漫游以获取某种 ID 值。您需要在此
查看这段代码: public async Task ConsumeAsync() { await a(); await b(); a
以下产生死锁错误消息(* 异常:线程在 MVar 操作中无限期阻塞)。我一步一步想通了,没看出问题。 在主线程上,创建一个 MVar,并将其提供给生产者,在新线程上运行 生产者启动,并在 listen
我想嵌入 3 个 NP-Complete 问题(其中 2 个已知是 NP-Complete,其中 1 个是我自己的想法)。我看到了“this question”并得到了关于从理论上重新解释嵌入问题的想
我刚刚测试了这段代码。 主要。 public class Main { /** * @param args */ public static void main(S
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我目前正在研究 open-std proposal为我正在处理的项目带来并行功能,但我遇到了 find_end 的障碍。 现在find_end可以描述为: An algorithm that sear
我正在编写看起来与此类似的代码: public IEnumerable Unfold(this T seed) { while (true) { yield retur
给定以下函数调用: f(g(), h()) 由于未指定函数参数的评估顺序(据我所知,在 C++11 中仍然如此),理论上是否可以执行 g() 和 h() 并行? 这种并行化只能在 g 和 h 已知相当
我在 C 中有两个项目: 第一个: include windows.h include stdio.h include tchar.h int main() { HANDLE hFile =
我在碰撞检测中有一个关于类似问题的问题,但它并不完全相同。我遇到了一个新游戏项目的问题(我正在尝试了解有关 HTML5 Canvases 和 Socket.io 的更多信息),其中我的碰撞不起作用。我
这个问题在这里已经有了答案: Why `alert()` after `setTimeout()` is not called as expected? (1 个回答) 关闭 8 年前。 为什么 s
在某些情况下,需要一种高效的内存来存储大量对象。要在 Java 中做到这一点,您不得不使用几个原始数组(请参阅下面的原因)或一个大字节数组,这会产生一些 CPU 开销以进行转换。 例子:你有一个 cl
我熟悉 PHP 函数如何映射到 PHP 下面的 C 代码中的 C 函数。我知道 C 中函数的含义以及 MACRO() 的含义。 我不明白什么是语言构造,例如 echo,在 PHP 中是什么意思。 最佳
刚刚将 libevent(1.4.8)、memcached(1.4.5)、pear 和 libmemcached(0.40) 安装到我的 lamp 服务器(运行 PHP 5.2.10 和 Centos
当谈到扩展方法时,类名似乎什么都不做,但提供了一个分组,这正是 namespace 所做的。一旦包含命名空间,我就会在命名空间中获得所有扩展方法。所以我的问题归结为:我可以从静态类中的扩展方法中获得一
我在我拥有的存储库(实际上是 fork 的)上使用 VS2015 GitHub 扩展。在 .gitignore 文件中的某些时候我有这个(从 fork 中获取,我没有添加 ignore ): ...
大家好。我会尽力解释我的问题,以便您能理解我。 在几个地方我发现它认为 Scala 比 Python 更快: https://www.quora.com/Which-one-is-faster-Sca
我是一名优秀的程序员,十分优秀!