У меня есть цикл for
который работает 20 000 раз с циклом for
внутри него, который также работает в 20 000 раз, что составляет до 400 миллионов.
в цикле for он добавляет 20 000 номеров в строку, а затем записывает эту строку в txt файл. после записи строка устанавливается пустым следующим образом: String Name = ""
;
поэтому я получу в общей сложности 20 000 текстовых файлов с каждыми 20 000 номерами в нем.
теперь, если цикл for создал около 200 файлов, он начинает исчерпывать память и в конечном итоге падает.
как я могу избежать этого?
- вот код -
public static void mapScanner()
{
String content = "";
for(int z = -10000; z < 10000; z++)
{
Util.CreateFile(z);
for(int x = -10000; x < 10000; x++)
{
Block block = Bukkit.getServer().getWorld("world").getBlockAt(x, Bukkit.getServer().getWorld("world").getHighestBlockYAt(x, z) -1, z);
if(block.getType() != Material.AIR)
{
content += Blocks.blockID(block.getType());
}
}
try
{
File file = new File("plugins/Map/" + z + ".txt");
System.out.println(content);
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
content = "";
System.out.println("The file : " + z + ".txt has been created and written.");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
block.getType()
просто возвращает число.
Общий код:
for(int x = 0; x < 20000; x++)
{
String content = "";
CreateFile(x);
for(int z = 0; z < 20000; z++)
{
content += "1";
}
try
{
File file = new File("Map/" + x + ".txt");
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
//System.out.println("The file : " + x + ".txt has been created and written.");
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void CreateFile(int z) {
File file = new File("Map/" + z + ".txt");
boolean fileCreated = false;
try {
fileCreated = file.createNewFile();
} catch (IOException ioe) {
//System.out.println("Error while creating empty file: " + ioe);
}
if (fileCreated) {
//System.out.println("Created empty file: " + file.getPath());
} else {
//System.out.println("Failed to create empty file: " + file.getPath());
}
}
У вас всегда будут проблемы с производительностью, если вы сохраните все содержимое в памяти, покажите мне код, который поможет вам.
Один из способов сделать это, это написать прямо в файл, поэтому не нужно держать строку в памяти.
Извините за мою грамматику, я не умею писать...
Попробуйте что-то вроде этого:
public static void mapScanner()
{
String content = "";
for(int z = -10000; z < 10000; z++)
{
File file = new File("plugins/Map/" + z + ".txt");
// if file doesn't exists, then create it, this inside another try.
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fw = new FileOutputStream(file);
OutputStream bw = new BufferedOutputStream(fw);
for(int x = -10000; x < 10000; x++)
{
Block block = Bukkit.getServer().getWorld("world").getBlockAt(x, Bukkit.getServer().getWorld("world").getHighestBlockYAt(x, z) -1, z);
if(block.getType() != Material.AIR)
{
string temp = Blocks.blockID(block.getType());
System.out.println(temp);
bw.write(temp.getBytes());
}
}
try
{
// Close all
bw.flush();
bw.close();
fw.close();
file.close();
System.out.println("The file : " + z + ".txt has been created and written.");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
замените String content = ""
на StringBuilder content = new StringBuilder()
и content += Blocks.blockID(block.getType())
с content.append(Blocks.blockID(block.getType()))
это должно заставлять вашу петлю работать намного быстрее. Я сомневаюсь, что это поможет с вашей проблемой OutOfMemory.
StringBuilder
, чтобы значительно уменьшить отток GC. Но это звучит так, как будто все должно быть в порядке, так как все должно быть подходящим для сбора. Короткая , но полная программа демонстрирует проблему будет сделать это намного проще , чтобы помочь вам.Util.CreateFile
?