0

I have been writing an updater for my game.

  1. It checks a .version file on drop box and compares it to the local .version file.

  2. If there is any link missing from the local version of the file, it downloads the required link one by one.

This is the error that it shows

Exception in thread "Thread-9" java.lang.OutOfMemoryError: Java heap space
at com.fox.listeners.ButtonListener.readFile(ButtonListener.java:209)
at com.fox.listeners.ButtonListener.readFile(ButtonListener.java:204)
at com.fox.listeners.ButtonListener.UpdateStart(ButtonListener.java:132)
at com.fox.listeners.ButtonListener$1.run(ButtonListener.java:58)

It only shows for some computers though and not all of them this is the readFile method

private byte[] readFile(URL u) throws IOException {
    return readFile(u, getFileSize(u));
}

private static byte[] readFile(URL u, int size) throws IOException {
    byte[] data = new byte[size];
    int index = 0, read = 0;
    try {
        HttpURLConnection conn = null;
        conn = (HttpURLConnection) u.openConnection();
        conn.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
        InputStream is = conn.getInputStream();
        progress_a = 0;
        progress_b = data.length;
        while(index < data.length) {
            read = is.read(data, index, size-index);
            index += read;
            progress_a = index;
        }
    } catch(Exception e) {
        e.printStackTrace();
    }

    return data;
}

private byte[] readFile(File f) {
    byte[] data = null;
    try {
        data = new byte[(int)f.length()];

        @SuppressWarnings("resource")
        DataInputStream dis = new DataInputStream(new FileInputStream(f));
        dis.readFully(data);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return data;
}

This is the main method that is ran

public void UpdateStart() {
    System.out.println("Starting Updater..");

    if(new File(cache_dir).exists() == false) {
        System.out.print("Creating cache dir.. ");
        while(new File(cache_dir).mkdir() == false);
        System.out.println("Done");
    }


    try {
        version_live = new Version(new URL(version_file_live));
    } catch(MalformedURLException e) {
        e.printStackTrace();
    }

    version_local = new Version(new File(version_file_local));

    Version updates = version_live.differences(version_local);

    System.out.println("Updated");

    int i = 1;
    try {
        byte[] b = null, data = null;
        FileOutputStream fos = null;
        BufferedWriter bw = null;


        for(String s : updates.files) {
            if(s.equals(""))
                continue;


            System.out.println("Reading file "+s);
            AppFrame.pbar.setString("Downloading file "+ i + " of "+updates.files.size());
            if(progress_b > 0) {
                s = s + " " +(progress_a * 1000L / progress_b / 10.0)+"%";
            }

            b = readFile(new URL(s));



            progress_a = 0;
            progress_b = b.length;

            AppFrame.pbar.setString("Unzipping file "+ i++ +" of "+updates.files.size());

            ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(b));
            File f = null, parent = null;
            ZipEntry entry = null;
            int read = 0, entry_read = 0;
            long entry_size = 0;
            progress_b = 0;

            while((entry = zipStream.getNextEntry()) != null)
                progress_b += entry.getSize();

            zipStream = new ZipInputStream(new ByteArrayInputStream(b));

            while((entry = zipStream.getNextEntry()) != null) {
                f = new File(cache_dir+entry.getName());
                if(entry.isDirectory())
                    continue;

                System.out.println("Making file "+f.toString());

                parent = f.getParentFile();
                if(parent != null && !parent.exists()) {
                    System.out.println("Trying to create directory "+parent.getAbsolutePath());
                    while(parent.mkdirs() == false);
                }

                entry_read = 0;
                entry_size = entry.getSize();
                data = new byte[1024];
                fos = new FileOutputStream(f);

                while(entry_read < entry_size) {
                    read = zipStream.read(data, 0, (int)Math.min(1024, entry_size-entry_read));
                    entry_read += read;
                    progress_a += read;
                    fos.write(data, 0, read);
                }
                fos.close();
            }

            bw = new BufferedWriter(new FileWriter(new File(version_file_local), true));
            bw.write(s);
            bw.newLine();
            bw.close();
        }
    } catch(Exception e) {
        e.printStackTrace();
        return;
    }

    System.out.println(version_live);
    System.out.println(version_local);
    System.out.println(updates);
    CacheUpdated = true;
    if(CacheUpdated) {
        AppFrame.pbar.setString("All Files are downloaded click Launch to play!");
    }

}

I don't get why it is working for some of my players and then some of my other players it does not i have been trying to fix this all day and i am just so stumped at this point but this seems like its the only big issue left for me to fix.

8
  • Is there something you don't understand about the error message? Commented Oct 25, 2015 at 14:38
  • @kayaman no what I don't understand is the fixing it issue Commented Oct 25, 2015 at 14:49
  • please provide information on how you launched the above code, i.e., which JVM parameters can be assumed here!? Commented Oct 25, 2015 at 15:04
  • Have you tried anything before asking this question on SO? Commented Oct 25, 2015 at 15:05
  • @MWiesner im just jarring it and running with no JVM Prams and im using 1.8 jdk to compile Commented Oct 25, 2015 at 15:12

2 Answers 2

0

Either increase the memory allocated to your JVM (How can I increase the JVM memory?), or make sure that the file being loaded in memory isn't gigantic (if it is, you'll need to find an alternate solution, or just read chunks of it at a time instead of loading the entire thing in memory).

Sign up to request clarification or add additional context in comments.

Comments

0

Do your update in several steps. Here's some pseudo-code with Java 8. It's way shorter than what you wrote because Java has a lot of built-in tools that you re-write much less efficiently.

// Download
Path zipDestination = Paths.get(...);
try (InputStream  in = source.openStream()) {
  Files.copy(in, zipDestination);
}

// Unzip
try (ZipFile zipFile = new ZipFile(zipDestination.toFile())) {
  for (ZipEntry e: Collections.list(zipFile.entries())) {
    Path entryDestination = Paths.get(...);
    Files.copy(zipFile.getInputStream(e), entryDestination);
  }
}

// Done.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.