Java分配:从预先存在/分配的池中分配对象
在Java程序中,当需要分配数千个类似大小的对象时,最好(在我看来)有一个带有保留项的“池”(这是一个单独的分配),这些保留项可以在需要时从中提取。这一个较大的分配不会像数千个较小的分配那样分割堆 显然,没有一种方法专门将对象引用指向内存中的地址(用于其成员字段)来设置池。即使新对象引用了池中的某个区域,仍然需要分配对象本身。如果不使用本机操作系统库,您将如何处理许多这样的分配?您可以尝试使用该库 也就是说,除非我有证据证明JVM没有做我需要的事情,否则我可能会推迟优化对象创建。您可以尝试使用该库Java分配:从预先存在/分配的池中分配对象,java,memory,allocation,Java,Memory,Allocation,在Java程序中,当需要分配数千个类似大小的对象时,最好(在我看来)有一个带有保留项的“池”(这是一个单独的分配),这些保留项可以在需要时从中提取。这一个较大的分配不会像数千个较小的分配那样分割堆 显然,没有一种方法专门将对象引用指向内存中的地址(用于其成员字段)来设置池。即使新对象引用了池中的某个区域,仍然需要分配对象本身。如果不使用本机操作系统库,您将如何处理许多这样的分配?您可以尝试使用该库 也就是说,除非我有证据证明JVM没有做我需要的事情,否则我可能会推迟优化对象创建。您可以尝试使用该
也就是说,除非我有证据证明JVM没有做我需要的事情,否则我可能会推迟优化对象创建。不用担心。除非您已经对正在运行的实际代码进行了大量测试和分析,并且知道这是垃圾收集的问题,并且JVM的工作做得不够好,否则请将您的时间花在其他地方。不要担心。除非您已经对正在运行的实际代码进行了大量测试和分析,并且知道这是垃圾收集的一个问题,并且JVM做得不够好,否则请将您的时间花在其他地方。如果您正在构建一个应用程序,其中可预测的响应时间非常重要,那么对象池,不管他们有多小,他们都会给你分红。同样,池也是您试图池化的数据集有多大以及您的机器有多少物理内存的一个因素 大量证据表明,对象池(无论对象有多小)对应用程序性能都是有益的 您可以使用两种级别的池:
- 基本对象(如向量)的池,每次必须使用向量形成地图或类似对象时,都会从池中检索这些对象
- 将最常用的高级复合对象池化
此外,在多线程应用程序中,您希望对分配和返回池的不同线程数量保持敏感。您当然不希望您的应用程序因争用而陷入困境,尤其是在您同时处理数千个对象的情况下。如果您正在构建一个应用程序,其中可预测的响应时间非常重要,那么对象池(无论它们有多小)将为您带来好处。同样,池也是您试图池化的数据集有多大以及您的机器有多少物理内存的一个因素 大量证据表明,对象池(无论对象有多小)对应用程序性能都是有益的 您可以使用两种级别的池:
- 基本对象(如向量)的池,每次必须使用向量形成地图或类似对象时,都会从池中检索这些对象
- 将最常用的高级复合对象池化
此外,在多线程应用程序中,您希望对分配和返回池的不同线程数量保持敏感。您当然不希望您的应用程序因争用而陷入困境,尤其是当您同时处理数千个对象时。@Dave和Casey,您不需要任何证据来证明连续内存布局提高了缓存效率,这是大多数需要高性能但遵循“过于理想化”OOP设计轨迹的OOP应用程序的主要瓶颈 人们通常认为GC是导致高性能Java应用程序性能低下的罪魁祸首,在修复它之后,只需保持这种状态,而不实际分析应用程序的内存行为。但是请注意,未缓存的内存指令本质上比算术指令更昂贵(并且由于内存访问计算缺口而变得越来越昂贵)。因此,如果您关心性能,您当然应该关心内存管理 缓存感知(Cache-aware)或更一般的面向数据的编程是在多种应用程序中实现高性能的关键,如游戏或移动应用程序(以降低功耗) 是DOP上的一个SO线程 这是索尼研发部门的幻灯片,展示了DOP应用于playstation游戏的实用性(需要高性能) 那么,如何解决Java通常不允许分配一块内存的问题呢?我的猜测是,当程序刚刚启动时,您可以假设已经分配的页面中几乎没有内部碎片。如果您现在有一个分配数千或数百万对象的循环,那么它们可能都是尽可能连续的。请注意,您只需要确保连续对象延伸到同一缓存线上,而在许多现代系统中,缓存线只有64字节。另外,如果您真的关心应用程序的(内存)性能,请查看DOP幻灯片 简而言之:总是一次分配多个对象(增加分配的时间局部性),并且,如果您的GC有碎片整理,请事先运行它,否则请尝试将此类分配减少到程序的开始 我希望这对你有帮助, -多米 PS:@Dave,公用池库不会连续分配对象。它只通过将分配放入一个引用数组、嵌入到堆栈、链表或simil中来跟踪分配