0

I'm generating a map from a spritesheet and when I increased the resolution of the sprite sheet from 25x25 to 50x50, I get an OutOfMemoryError: Java heap space. I tried using threads to generate 5 different parts of the map but the error still occurs. I've seen commands such as "java -Xmx6144M -d64" but i'm not sure how or where to implement that in my program. I want to use BufferedImage but I'm new and not sure how to exactly.

Main class:

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main extends JPanel implements KeyListener {
    
    private static SpriteSheet sc;

    private int x = 0;
    private int y = 0;

    private final static int numOfTiles = 50;
    private final int tileSize = 30;
    private final int numOfThreads = 5;

    public Main() {

        JFrame f = new JFrame();
        setLayout(null);
        this.setSize(numOfTiles * 100, numOfTiles * 100);

        f.setLayout(null);

        f.add(this);
        f.setSize(1000, 1000);
        f.setUndecorated(true);
        f.setLocationRelativeTo(null);
        this.setBackground(new Color(150, 150, 150));
        f.addKeyListener(this);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    public static void main(String args[]) {

        new Main().start();

    }

    public void start() {
        Thread fps = new Thread() {
            public void run() {
                FPS();
            }
        };

        fps.start();

        mapThread();
    }

    private int i;

    public void mapThread() {
        Thread threads[] = new Thread[numOfThreads];
        SpriteSheet[] spriteSheet = new SpriteSheet[5];

        for (i = 0; i < threads.length; i++) {

            threads[i] = new Thread() {
                public void run() {
                    mapSetup(threads.length, i, spriteSheet[i]);
                }
            };

            threads[i].start();

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.exit(0);
            }
        }
    }

    void mapSetup(int threadNum, int thread, SpriteSheet spriteSheet) {

        Random ran = new Random();
        int l = 0;

        JLabel[][] tiles = new JLabel[numOfTiles / threadNum][numOfTiles / threadNum];
        spriteSheet = new SpriteSheet();

        for (int r = 0; r < numOfTiles; r++) {
            for (int c = 0; c < numOfTiles / threadNum; c++) {

                l = ran.nextInt(5);
                Image i = spriteSheet.getTile(l, tileSize);
                ImageIcon ii = new ImageIcon(i);

                JLabel j = new JLabel(ii);

                j.setBounds((c * tileSize) * thread, (r * tileSize) * thread, tileSize, tileSize);

                this.add(j);
            }
        }
    }

    void bushes() {

    }

    void tilePlace(JLabel[][] tiles) {

        // this constantly repositions the tiles when a character moves
        while (true) {
            for (int r = 0; r < numOfTiles; r++) {
                for (int c = 0; c < numOfTiles; c++) {
                    tiles[r][c].setBounds(x + (c * 100), y + (r * 100), 100, 100);

                }
            }
        }
    }

    static boolean Z = false;
    static boolean S = false;
    static boolean Q = false;
    static boolean D = false;

    public void keyTyped(KeyEvent e) {

    }

    public void keyPressed(KeyEvent e) {

        int k = e.getKeyCode();

        if (k == KeyEvent.VK_Z) {
            Z = true;
        }

        if (k == KeyEvent.VK_S) {
            S = true;
        }

        if (k == KeyEvent.VK_D) {
            D = true;
        }

        if (k == KeyEvent.VK_Q) {
            Q = true;
        }

        if (k == KeyEvent.VK_ESCAPE) {
            System.exit(0);
        }

    }

    public void keyReleased(KeyEvent e) {

        int k = e.getKeyCode();

        if (k == KeyEvent.VK_Z) {
            Z = false;
        }

        if (k == KeyEvent.VK_S) {
            S = false;
        }

        if (k == KeyEvent.VK_D) {
            D = false;
        }

        if (k == KeyEvent.VK_Q) {
            Q = false;
        }
    }

    Thread mov = new Thread() {
        public void run() {
            movement();
        }
    };

    public void movement() {

        while (true) {

            if (Z && y <= 0) {
                y++;
            }
            if (S && y >= (-1) * (numOfTiles * 100) + 1000) {
                y--;

            }
            if (D && x >= (-1) * (numOfTiles * 100) + 1000) {
                x--;

            }
            if (Q && x <= 0) {
                x++;

            }

            try {
                Thread.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    void FPS() {
        while (true) {
            repaint();

            try {
                Thread.sleep(1000 / 60);

            } catch (InterruptedException e) {

            }
        }
    }

}

SpriteSheet class:

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class SpriteSheet {

    final int W = 50;
    final int H = 50;

    BufferedImage spriteSheet;

    public Image getTile(int tile, int tileSize) {

        if (new File("img/SpriteSheet.png").exists()) {

            if (tile < 6) {
                try {
                    spriteSheet = ImageIO.read(new File("img/SpriteSheet.png"));
                } catch (IOException e) {
                    e.printStackTrace();
                }

                int tileX = 1 + tile + (tile * 50);
                int tileY = 1 + (0 * 50);

                Image i = spriteSheet.getSubimage(tileX, tileY, 50, 50);

                Image newImage = i.getScaledInstance(tileSize, tileSize, Image.SCALE_DEFAULT);

                return newImage;
            }

            if (tile < 27 && tile > 24) {

                tile = tile - 25;

                int tileX = 1 + tile + (tile * 25);

                try {
                    spriteSheet = ImageIO.read(new File("img/SpriteSheet.png"));
                } catch (IOException e) {
                    e.printStackTrace();
                }

                Image i = spriteSheet.getSubimage(tileX, 26, 25, 25);

                Image newImage = i.getScaledInstance(tileSize, tileSize, Image.SCALE_DEFAULT);

                return newImage;
            }
        } else {

            System.err.println("no files found");

            return null;

        }
        return null;

    }

}
  • 1
    Does this answer your question? [How to deal with "java.lang.OutOfMemoryError: Java heap space" error?](https://stackoverflow.com/questions/37335/how-to-deal-with-java-lang-outofmemoryerror-java-heap-space-error) – Spectric Oct 05 '20 at 15:34
  • @Spectric I don't know how to use "-Xmx512m -XX:MaxPermSize=512m" in my program, I need to see an example of a program using it. – nicolas gilliot Oct 05 '20 at 15:39
  • You don't implement it in your program, you specify it on the commandline that starts your program. – Mark Rotteveel Oct 05 '20 at 15:58

0 Answers0