2011-03-18 60 views
0

我的一个项目存在一些内存问题。一下就在我的程序的几个位置追踪内存之后,我追溯了问题这一行:如何正确解引用缓冲区?

(FloatBuffer)lightBuffer.asFloatBuffer().put(lightAmbient).flip() 

我使用得到缓冲的功能直线距离,但似乎是float缓冲区不会被清空在它被使用之后。 那么如何在java中正确地清空/取消引用缓冲区?

ps:我尝试了clear()方法,但根据只重置缓冲区的java文档;它不会从中删除数据。

+0

为什么不够清楚?之后您可以重新使用缓冲区,就好像数据已发布一样。或者,您可以使缓冲区符合垃圾回收条件并创建一个新的垃圾回收站。 – Thomas 2011-03-18 20:42:57

回答

2

假设你lightBuffer是一个字节缓冲区(似乎没有其它类有一个方法asFloatBuffer),你的FloatBuffer目的是仅围绕相同的基础byte[]或本机内存的包装。

这个FloatBuffer对象不会再吃任何更多的内存(但使用与lightBuffer使用的内存相同的内存),但它可能会阻碍ByteBuffer的垃圾回收 - 但看起来你正在重用这个,不是吗?

所以目前似乎没有问题(除了你不知道有几个缓冲区使用相同的内存)。

+1

+1只是一个注释:有时(很少)有很多正在分配的直接缓冲区(可能是另一个问题)没有足够的GC压力来使它们“死亡”得足够快。有一些使用“内部”方法的黑客迫使直接缓冲区尽早释放其支持。 – 2011-03-18 21:09:39

+0

lightBuffer是一个ByteBuffer,是的(抱歉..忘了包括它)。我也在重复使用lightBuffer。我也不知道他们使用相同的内存。那么我想我的记忆问题是在别的地方。 – Bartvbl 2011-03-18 21:33:25

+0

事情是;一旦我注释掉这一行,程序的内存使用量就是不变的。一旦启用它,它就会开始以大约300 Kb/s的速度泄漏内存。所以我完全被这个事实困惑,尤其是因为你说内存是共享的;它不应该这样做。 – Bartvbl 2011-03-18 21:39:24

2

您是否在某处存储了对此缓冲区的引用?我不认为你可以明确地“从缓冲区中删除数据”,并且System.gc()在这里不会帮助你。

垃圾回收器应该自动为您处理,除非您维护对此缓冲区的引用。

+0

+1只是一个注释:有时(很少)有直接缓冲区,其中很多正在分配(可能是另一个问题),没有足够的GC压力使它们“死亡”足够快,因为直接缓冲区的数据不受管理。有一些使用“内部”方法的黑客迫使直接缓冲区尽快释放它的支持,但不幸的是,没有可关闭/一次性接口。当然,使用这样一个缓冲区和一个已发布的后台会导致令人讨厌的异常:-) – 2011-03-18 21:11:19

+0

我正在创建缓冲区对象,然后将它传递给一个openGL函数。上面的代码来自该函数的其中一个参数,所以我猜这不应该在后面留下任何参考,除非openGl保留它。哪个_不应该是这种情况 – Bartvbl 2011-03-18 21:48:32

0

呃,你没有。

这些NIO缓冲区不会浪费时间,它们会覆盖缓冲区中的数据并移动标记。

如果你想摆脱它,你必须摆脱它的所有引用,并提供给GC,以便它可以收集。