“线程中的异常”;螺纹-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
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进行编译