2014-10-29 53 views
8

我目前有一个空白的LibGDX应用程序,它确实没有没有。它不渲染任何东西,也不更新任何东西。这只是一个空的Screen。当我将应用程序部署到Android时,我遇到了一些可怕的内存消耗。使用DDMS我创建以下堆转储应用程序时,我的设备上运行:Android图形巨大的堆内存消耗? - LibGDX

enter image description here

最显著使用内存为13.163 MB 1字节数组分配。这不是半堆吗?!

我检查了分配,看到什么指着被分配的大小:

enter image description here

现在使用Eclipse MAT我分析堆转储:

enter image description here

所以内存的高度使用仍然来自byte []数组。 分析字节[]段还我想出了这一点:

enter image description here

我现在看到了巨大的byte []分配是从Android的图形来。我甚至没有画任何东西!有什么办法可以避免让这个应用的Android图形部分占用一半的堆。这只会导致在事情正在进行时发生超量垃圾收集,或者这是正常的,我只需要处理它呢?

注:我与libGDX版本1.4在三星Galaxy S4运行这个(或任何最新版本)

更新:我没有发现,14-13MB字节数组分配是正常的应用但我仍然有问题。我的堆大小太小。如果Android图形占用了我的一半堆,我就没有什么用处,垃圾收集器变得疯狂了。在另一个我用老版本的libgdx创建的应用程序(一个不可否认更糟糕的应用程序)和堆大小为73 Mb。我怎样才能增加堆大小?我认为73 MB是相当大的,你可以看到大部分没有被使用。这里是旧的应用程序的堆统计: enter image description here

+1

您是否尝试过分配一些垃圾来尝试超过第一个具有小堆大小的应用程序的堆大小?如果你没有,那就这样做。完成后会自动增加堆大小吗? – 2014-11-06 11:47:37

回答

6

Android版本2.3之后,除了使用android:largeHeap属性之外,您无法对堆的大小进行任何操作。

有两种方法来欺骗如果你想一大堆无关紧要的:

  1. 使用原生API来分配内存:因为它增加了复杂性不是一个好主意,如果你不计划在本机代码中执行操作,
  2. 在执行前分配一个不必要的大对象以获得所需的堆空间:虽然它会给您足够的堆空间一次,但不保证堆大小将保持不变。

但是,如果在需要时调整大小,初始堆大小不是问题。我对游戏生命周期中的内存管理的看法与上面列出的两件事以及你可能做的有些不同。

对于某个关卡或舞台等,您不应该在需要的时候在确切的时间分配内存。这不仅会在分配内存时造成口吃,还会由于可能的存储I/O而造成口吃。任何东西,如声音,图形,字体等都应该在关卡之前准备好。这就是为什么很多游戏都有“加载”屏幕的原因。在开始比赛之前,你应该准备任何你可以做的事情。

对于一个小舞台来说,这样做确实不错 - 但仍然不好。随着事情变得复杂,它会降低性能。很多游戏(如体育游戏,赛车游戏等)在开始游戏之前都会进行分配。其他人也可以尽可能多地。一些开放的世界游戏(如GTA)不会加载地图中的所有地图对象,但它们具有绘制距离,因此当您在地图中移动时它们将绘制,并且当内存没有更多空间时它们会从内存中移除最远的对象。

[为什么你的应用程序与旧的LibGDX版本有更多的堆大小可能是一个分配,导致堆大小增加和释放一些堆,以便你得到一个很好的30%的使用率。

+0

谢谢您的帮助! – grimrader22 2014-11-10 15:47:29

+0

不客气! – 2014-11-10 16:16:22

1

您可以在Android清单分配给此属性值:

android:largeHeap="true"

注意,这只能在Android 3.0以上版本

+0

将这添加到清单中后,堆大小仍然保持在26.465Mb,它远没有接近其他应用程序的73.855Mb。我最近发现,如果这个值是真的,如果内存不足,堆只会调整大小,而我不知道这个值。 GC_FOR_ALLOC会导致应用程序口吃频繁出现,我希望可以通过增加堆大小来减少GC_FOR_ALLOC。在我提到的第二个应用程序中,只有30%被使用,这意味着GC_FOR_ALLOC不会经常发生。在第一个应用程序中使用了60%。 – grimrader22 2014-10-31 12:39:23

+0

即使我在技术上不需要它,有没有办法扩大堆大小? – grimrader22 2014-10-31 12:39:47

+0

恐怕我不知道那么。我知道的唯一方法就是上述。 – Bowersbros 2014-10-31 14:44:27

1

右对齐工作点击分配的对象,选择“trace to GC root”,“不包括弱引用”

http://www.youtube.com/watch?v=_CruQY55HOk

+0

这会帮助我解决什么问题? – grimrader22 2014-10-30 21:50:35

+0

你可以找到如何分配对象与其他对象连接,并以这种方式找到内存泄漏。 https://developer.android.com/tools/debugging/debugging-memory.html使用Eclipse内存分析器工具 – konmik 2014-10-31 13:53:08

+0

我最近将此答案标记为不是答案,但该标记被拒绝。它似乎是有效的内容,但缺乏一个很好的答案。为了清晰起见,您可能想要扩展它? – brandonscript 2014-11-12 18:23:09