【问题标题】:How can I avoid a byte[] memory leak?如何避免 byte[] 内存泄漏?
【发布时间】:2011-08-21 15:17:23
【问题描述】:

我有一个 byte[] 的内存泄漏,我想了解更多关于这个的信息,以防止它在将来发生。

这是我的java代码:

package server.world;

import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class WalkingHandler {

    public static final int WIDTH = 12000;
    public static final int HEIGHT = 9900;

    private final TiledMap map;

    private WalkingHandler() {
        this.map = new TiledMap(WIDTH, HEIGHT);
    }

    private static class SingletonContainer {
        private static final WalkingHandler SINGLETON = new WalkingHandler();
    }

    public static WalkingHandler getSingleton() {
        return SingletonContainer.SINGLETON;
    }

    public boolean traversable(int x, int y, int direction) {
        int flag = map.getFlag(x, y);
        //System.out.println(direction);
        if (direction == 0 && (flag == 1 || flag == 4 || flag == 6 || flag == 7 || flag == 9 || flag == 11 || flag == 13 || flag == 14)) {
            return false;
        } else if (direction == 4 && (flag == 1 || flag == 7 || flag == 15 || flag == 10 || flag == 11 || flag == 12 || flag == 14 || flag == 5)) {
            return false;
        } else if (direction == 8 && (flag == 1 || flag == 2 || flag == 3 || flag == 4 || flag == 5 || flag == 6 || flag == 7 || flag == 12)) {
            return false;
        } else if (direction == 12 && (flag == 1 || flag == 3 || flag == 6 || flag == 9 || flag == 10 || flag == 11 || flag == 12 || flag == 8)) {
            return false;
        } else if(flag > 0 && flag < 15) {
            return false;
        }
        return true;
    }

    public void initialize() throws Exception {
        long delta = System.currentTimeMillis();
        RandomAccessFile raf = new RandomAccessFile("data/lolmap.bin", "r");
        FileChannel channel = raf.getChannel();
        MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
        int length = buffer.getInt();
        for(int i = 0; i < length; i++) {
            int x = buffer.getShort();
            int y = buffer.getShort();
            byte flag = buffer.get();
            map.flag(x, y, flag);
        }
        System.out.println("Loaded clipmap in " + (System.currentTimeMillis() - delta) + "ms.");
    }

    private static class TiledMap {

        private final byte[] plane;

        public TiledMap(int width, int height) {
            this.plane = new byte[width * 10000 + height];
        }

        public int getFlag(int x, int y) {
            return plane[x * 10000 + y];
        }

        public void flag(int x, int y, byte flag) {
            this.plane[x * 10000 + y] = flag;
        }

    }

}

有人介意指出我做错了什么吗?

【问题讨论】:

  • 请在此处粘贴您的代码,而不是在 pastebin 上链接到它。
  • @Aleksandr:您实例化 TiledMap 多少次?除此之外,“x*10000 + y”是违反直觉的。大多数游戏设计师会使用“y*1000 + x”来存储/定位“事物”在包含 2D 事物的一维数组中。此外,你的凌乱的 if direction / flags 东西肯定可以用更好的方式重写。
  • 您在寻找什么内存泄漏?您分配内存并使用它。只要您不需要其他任何内存,它就不会被垃圾收集,即使它没有被引用,据我所知,所有内存都在您的情况下。因此,如果您寻求帮助,请说明您在哪里看到的问题。

标签: java memory memory-leaks


【解决方案1】:

您正在创建一个大小为 12000*10000+9900 的数组,即 120_009_900 字节(这甚至被错误地初始化:您应该分配 12000*9900 空间并使用 x*height+y 获取它们)

private static class TiledMap {

    private final byte[] plane;
    private final int width,height;

    public TiledMap(int width, int height) {
        this.plane = new byte[width * height];
        this.width = width;
        this.height = height;
    }

    public int getFlag(int x, int y) {
        return plane[x * height + y];
    }

    public void flag(int x, int y, byte flag) {
        this.plane[x * height + y] = flag;
    }

}

但是你最好先从文件中获取你需要的空间然后分配

【讨论】:

  • 我注意到它实际上不是内存泄漏,但它使用 byte[] 非常糟糕。查看服务器的此快照。 i55.tinypic.com/2vv9z5s.png
  • @akek 是的,这就是一个数组
  • 关于如何减少它的任何建议?大声笑我可能会使用一种新方法来阅读地图大声笑。
  • @alek 正如我所说,首先发现所需的大小然后分配
猜你喜欢
  • 1970-01-01
  • 2020-05-13
  • 2018-04-08
  • 2013-06-24
  • 1970-01-01
  • 2016-08-14
  • 2015-08-27
相关资源
最近更新 更多