gpt4 book ai didi

java - GC 应用程序运行缓慢后

转载 作者:搜寻专家 更新时间:2023-11-01 03:47:38 26 4
gpt4 key购买 nike

我有一个在 JVM 上运行的应用程序(游戏)。

游戏的更新逻辑(每秒运行 60 次)在使用了大约 25% 的“时间片”(1/60 秒)后结束,然后 hibernate 剩下的 75%。但是当 GC 收集器开始运行时,它会上升到 75-200%,并在剩下的执行过程中保持在那里。

游戏使用了大约 70Mb 的堆,并以大约 1-2mb/s 的速度增长。当 GC 运行时,它会回到 70Mb,因此没有真正的内存泄漏。以后我会尽量降低这个数字,但在这个范围内应该问题不大。

我使用的 JVM 8 没有运行时参数或标志,不确定哪个 GC 会给我。

我已经尝试将堆设置为不同的大小,但它不会影响这种现象。

关于为什么会这样,我有两种理论:

  1. GC 无意中以一种导致更新循环中缓存垃圾的方式对我的堆进行碎片化。我的逻辑在循环遍历并更新数据时从数据邻近性中受益匪浅。会不会是把一些数据shuffle到old area,同时把一些数据留在young(the nursery)?

  2. 突然的 GC 处理触发了我的操作系统,使其意识到我的主要更新进程不需要像当前那样多的 CPU 资源,从而降低了它的优先级。 (但是,即使我跳过 thread.sleep() 以 hibernate 未使用的 CPU 使用率,该现象仍然存在。

你怎么看。我的理论是否合理,是否可以对其进行任何处理,或者我是否需要切换到 C 语言?我对 GC 的了解有限。

附言作为旁注,通常 update() 在 GC 后完成 75%。当我使用 VSync 时,我得到了 200% 这样的数字。

最佳答案

不再有效:

我做了一个测试,完全毁了我的架构。我有这个,这是应用程序的瓶颈:

class Physics{
Vec2 centre;
Rec hitbox;
Vec2 speed;
Vec2 acc;
...

public void update(){ //critical method
centre.doThings();
hitbox.doThings();
etc...
}

}

并将其更改为仅使用原语:

class Physics{
double centreX,centreY;
double x1,x2,y1,y2;
double speedX,speedY;
double accX,accY;
...

public void update(){ //critical method
implementation of methods above...
etc...
}

}

这是因为,至少,java 保证类原始成员按照声明的顺序存储在堆的类头之下。虽然对对象的引用可以是堆另一端的地址。

这与压缩 GC 一起给了我一个很好的提升,我认为这是缓存命中率的增加。它摧毁了我的架构,但这是我愿意付出的代价。

现在游戏稳定运行在15%,现在我把自己的帖子标记为答案。

编辑:那只是一个糊涂人的胡言乱语。以上只给了我一个小的性能提升 - 其余的是由于应用程序中的错误,因此不能证明体系结构更改的合理性。不过,压缩 GC 有所帮助。

关于java - GC 应用程序运行缓慢后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40671352/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com