Java大对象集的内存分配
我目前正在用java开发一个游戏引擎,但是在堆上分配大量对象时我遇到了性能问题,例如
public class GLParticleSystem {
private GLParticle[] particles = new GLParticle[2000];
private int numberOfParticles;
public GLParticleSystem(numberOfParticles) {
this.numberOfParticles = numberOfParticles;
}
public void init() {
for (int i = 0; i < numberOfParticles; i++) {
particles[i] = new GLParticle();
}
}
}
上面的代码在启动时将遭受大量帧下降,因为剪切级别分配,我想知道是否有我遗漏的东西或一些关于解决这个问题的文字。
更新
我的GLParticle类的请求数据成员。
public class GLParticle {
private GLSpriteSheet image = null;
private float x;
private float y;
private float vX;
private float vY;
private float alpha;
private float alphaStep;
private boolean isDead;
private long startTime;
private long lifeTime;
private final float u = 480f;
private final float v = 504f;
}
谢谢加里
I'm currently working on a game engine in java, however I'm having preformance issues when allocating large sets of objects on the heap, for example
public class GLParticleSystem {
private GLParticle[] particles = new GLParticle[2000];
private int numberOfParticles;
public GLParticleSystem(numberOfParticles) {
this.numberOfParticles = numberOfParticles;
}
public void init() {
for (int i = 0; i < numberOfParticles; i++) {
particles[i] = new GLParticle();
}
}
}
The above piece of code will suffer a massive frame drop upon initiation, due to shear level of allocation, I was wondering if there is something I am missing or some text on solving this issue.
Update
Requested data members of my GLParticle class.
public class GLParticle {
private GLSpriteSheet image = null;
private float x;
private float y;
private float vX;
private float vY;
private float alpha;
private float alphaStep;
private boolean isDead;
private long startTime;
private long lifeTime;
private final float u = 480f;
private final float v = 504f;
}
Thanks Gary
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以为
GLParticle
的每个成员创建十个单独的 2000 数组,并使用 Flyweight 模式。在此实现中,每个 GLParticle 都会将其索引以及包含数组的GLParticleSystem
实例传递到 GLParticleSystem 的数组中。这稍微麻烦一些,但这是当大量细粒度对象在 CPU 周期方面变得过于昂贵时要尝试的第一个模式。You can create ten separate arrays of 2000 for each member of
GLParticle
, and use Flyweight Pattern. In this implementation, each GLParticle would be passed its index into theGLParticleSystem
's arrays, along with an instance ofGLParticleSystem
that contains the arrays. This is slightly more cumbersome, but this is the first pattern to try when having lots of fine-grained objects becomes too expensive in terms of the CPU cycles.您正在 init 中创建新对象,您可能会发现对象池很有帮助。与其每次需要一个对象时都创建对象,不如一开始就创建一个大集合。然后,每当您需要一个对象时,您都会获取一个预先分配的对象。
http://en.wikipedia.org/wiki/Object_pool_pattern
You are making new objects in your init, you might find Object Pooling to be helpful. Instead of creating objects every time you want one you make a large set to begin with. Then whenever you need an object you take a preallocated object.
http://en.wikipedia.org/wiki/Object_pool_pattern
private static Final float U = 480f;
和V
会有一点帮助。看看 FutureTask 就可以做这样的事情。
private static final float U = 480f;
andV
would help a tiny bit.Look at FutureTask for doing such things.
虽然我对您仅分配 2000 个对象时出现性能问题感到有些惊讶,但我很遗憾地说,没有简单的方法可以解决您的问题。 Java 由于缺乏 C/C# 结构类型,因此与这些语言相比,在此用例中并不是一种非常高效的语言。您的问题有 3 种解决方案。
1) 在需要对象之前预先分配它们。虽然它有效,但这并不是一个很好的解决方案,因为您必须手动将未使用的对象返回到预先分配的对象池中。
2) 鉴于 GLParticle 是小对象(56 字节),如果您的用法允许,可以将其重写为 GLParticles 类,该类存储固定数量的 GLParticle 对象的数据。
这既提高了空间效率,又提高了分配(和收集)速度。
3) 如果您使用的 JVM 有这些,请尝试优化托儿所和线程本地 GC 池的大小。
While I am somewhat surprised that you have performance issues with allocating only 2000 objects, I am sorry to say that there is no simple fix for your problems. Java, as it lacks C/C# struct types, is not a very efficient language in this usecase when compared to those languages. There are 3 solutions for your problem.
1) Preallocate objects before you need them. While it works this is not a great solution as you have to manually return unused objects to a pool of preallocated objects.
2) Given that GLParticle is small object (56bytes) it can be rewritten, if your usage allows it, as GLParticles class which stores data for a fixed amout of GLParticle objects.
This is both more space efficient and far faster to allocate (and collect).
3) Try to optimize size of nursery and thread local GC pools if JVM which are you using has those.