“线程中的异常”;螺纹-9“;java.lang.OutOfMemoryError:java堆空间

“线程中的异常”;螺纹-9“;java.lang.OutOfMemoryError:java堆空间,java,heap,Java,Heap,我一直在为我的游戏编写更新程序 它在下拉框中检查.version文件,并将其与本地.version文件进行比较 如果文件的本地版本中缺少任何链接,它将逐个下载所需的链接 这就是它显示的错误 Exception in thread "Thread-9" java.lang.OutOfMemoryError: Java heap space at com.fox.listeners.ButtonListener.readFile(ButtonListener.java:209) at com.fox

我一直在为我的游戏编写更新程序

  • 它在下拉框中检查.version文件,并将其与本地.version文件进行比较

  • 如果文件的本地版本中缺少任何链接,它将逐个下载所需的链接

  • 这就是它显示的错误

    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)
    
    它只显示了一些计算机,而不是所有的计算机,这是readFile方法

    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;
    }
    
    private byte[]读取文件(URL u)引发IOException{
    返回readFile(u,getFileSize(u));
    }
    私有静态字节[]读取文件(URL u,int size)引发IOException{
    字节[]数据=新字节[大小];
    int-index=0,read=0;
    试一试{
    HttpURLConnection conn=null;
    conn=(HttpURLConnection)u.openConnection();
    conn.addRequestProperty(“用户代理”、“Mozilla/4.0(兼容;MSIE 6.0;Windows NT 5.1)”);
    InputStream is=conn.getInputStream();
    进度a=0;
    进度_b=数据长度;
    while(索引<数据长度){
    read=is.read(数据、索引、大小索引);
    索引+=读取;
    进度a=指数;
    }
    }捕获(例外e){
    e、 printStackTrace();
    }
    返回数据;
    }
    私有字节[]读取文件(文件f){
    字节[]数据=null;
    试一试{
    数据=新字节[(int)f.length()];
    @抑制警告(“资源”)
    DataInputStream dis=新DataInputStream(新文件InputStream(f));
    dis.readFully(数据);
    }捕获(IOE异常){
    e、 printStackTrace();
    }
    返回数据;
    }
    
    这是运行的主要方法

    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!");
        }
    
    }
    
    public void UpdateStart(){
    System.out.println(“启动更新程序…”);
    if(新文件(cache_dir).exists()==false){
    系统输出打印(“创建缓存目录”);
    while(新文件(cache_dir).mkdir()==false);
    系统输出打印项次(“完成”);
    }
    试一试{
    version_live=新版本(新URL(version_file_live));
    }捕获(格式错误){
    e、 printStackTrace();
    }
    版本\本地=新版本(新文件(版本\文件\本地));
    版本更新=Version\u live.differences(Version\u local);
    系统输出打印项次(“更新”);
    int i=1;
    试一试{
    字节[]b=null,数据=null;
    FileOutputStream=null;
    BufferedWriter bw=null;
    用于(字符串s:updates.files){
    如果(s.等于(“”)
    继续;
    System.out.println(“读取文件”+s);
    AppFrame.pbar.setString(“下载文件”+i+”of“+updates.files.size());
    如果(进度>0){
    s=s++(进度a*1000L/进度b/10.0)+“%”;
    }
    b=读取文件(新URL);
    进度a=0;
    进度=长度;
    AppFrame.pbar.setString(“解压文件”+i+++“+updates.files.size()”);
    ZipInputStream zipStream=新的ZipInputStream(新的ByteArrayInputStream(b));
    文件f=null,父文件=null;
    ZipEntry条目=null;
    int read=0,entry_read=0;
    长输入_大小=0;
    进展b=0;
    while((entry=zipStream.getnextery())!=null)
    progress_b+=entry.getSize();
    zipStream=新ZipInputStream(新的ByteArrayInputStream(b));
    while((entry=zipStream.getnextery())!=null){
    f=新文件(cache_dir+entry.getName());
    if(entry.isDirectory())
    继续;
    System.out.println(“生成文件”+f.toString());
    parent=f.getParentFile();
    if(parent!=null&&!parent.exists()){
    System.out.println(“尝试创建目录”+parent.getAbsolutePath());
    while(parent.mkdirs()==false);
    }
    条目读取=0;
    entry_size=entry.getSize();
    数据=新字节[1024];
    fos=新文件输出流(f);
    while(条目读取<条目大小){
    read=zipStream.read(data,0,(int)Math.min(1024,entry_size-entry_read));
    条目_read+=已读;
    进度a+=读取;
    fos.写入(数据,0,读取);
    }
    fos.close();
    }
    bw=新的BufferedWriter(新的FileWriter(新文件(版本文件本地),true));
    bw.写入;
    换行符();
    bw.close();
    }
    }捕获(例外e){
    e、 printStackTrace();
    返回;
    }
    System.out.println(实时版本);
    System.out.println(本地版本);
    System.out.println(更新);
    CacheUpdated=true;
    如果(缓存更新){
    AppFrame.pbar.setString(“所有文件都已下载,请单击启动播放!”);
    }
    }
    

    我不明白为什么它对我的一些玩家起作用,然后对我的其他一些玩家起作用。我整天都在试图解决这个问题,我对此感到非常困惑,但这似乎是我要解决的唯一大问题。

    要么增加分配给JVM()的内存,或者确保加载到内存中的文件不是巨大的(如果是,您需要找到一个替代解决方案,或者一次只读取一大块文件,而不是将整个文件加载到内存中)。

    分几个步骤进行更新。下面是一些Java8的伪代码。它比您编写的要短得多,因为Java有许多内置工具,您编写这些工具的效率要低得多

    // 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.
    

    关于错误消息,您是否有什么不明白的地方?@kayaman no我不明白的是修复问题请提供有关您如何启动上述代码的信息,即,这里可以假设哪些JVM参数!?在问这个问题之前,你试过什么吗?@MWiesner我只是在不使用JVM的情况下运行它,我使用1.8 jdk进行编译