のようです。はじめに
こんにちは。私は今約2週間問題が発生していると私ははできませんは、それが起こっている理由を見つけることができるようです。 だから、どういう場合ですか?私のプロジェクトのHashetの最大サイズは961
ラフ説明
私は保存したファイルのすべての領域のファイルを読み込み、それらをチェックしのMinecraftツールを、書いています。彼らがプレイヤーが置かれたブロックを持っている場合、そのブロックが入っているチャンクは安全とマークされ、後で削除されません。そうでなければ、いくつかのエンキューが発生するはずであるので、エンキュープロセスが完了した後にチャンクが削除されます。それは私が使用していますHashSetの中に961個の要素に当たるまで
問題
プログラムは、問題なく動作しているようです。 ハッシュセットには、チャンクが安全であるとマークされているかどうかを判断するために使用される文字列が含まれています。 961個の要素があると、メモリがなくなったかのように、それ以上は追加できないように振る舞いますが、実際にはそうではありませんが、2GBのメモリが割り当てられています。私は多くの異なるパラメータで、それを何度もテストしてみたが、HashSetのに要素を追加し、それが961にアップトップス、そしてないよりも、それ以上の追加んが、それはエラーに961
で
トップスそれ。 RAMも2GBでテストされましたが、運はありません。
コード
ここに私のコードです。それに圧倒されないでください、それはかなり簡単です。
Options
クラスは、いくつかのオプションをロードするクラスです。言及する価値はありません。
Main
クラス:
public class Main {
Options options = new Options();
Deleter deleter;
public Main() {
deleter = new Deleter(this);
}
public static void main(String[] args) {
Main main = new Main();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Load world?");
System.out.println("(Y for yes/Q for quit): ");
String s = br.readLine();
while (!s.equalsIgnoreCase("Q")) {
if (s.equalsIgnoreCase("Y")) {
main.deleter.loadWorld();
System.out.println("Enqueue?");
System.out.println("(E for enqueue/Q for quit): ");
s = br.readLine();
while (s.equalsIgnoreCase("E")) { // While user wants to enqueue
main.deleter.enqueue();
System.out.println("Delete?");
System.out.println("(E for enqueue/D for delete/Q for quit)");
s = br.readLine();
}
if (s.equalsIgnoreCase("D")) {
main.deleter.delete();
}
}
} // If input == Quit, do this
} catch (IOException e) {
e.printStackTrace();
}
}
}
Deleter
クラス
public class Deleter {
private Options options;
private ArrayList<File> files = new ArrayList<>(1000);
private HashSet<String> safeChunks = new HashSet<>(20000);
private ArrayList<Integer> blockIDsList = new ArrayList<>(100);
private int totalChunksEnqueued = 0;
private int chunksEnqueued = 0;
public Deleter(Main main) {
this.options = main.getOptions();
totalChunksEnqueued = 0;
}
public void loadWorld() {
String folderName = options.getSaveFolderFile().getParentFile().getName();
System.out.println("--------Loading world: " + folderName + "--------");
File filesTemp[] = options.getSaveFolderFile().listFiles();
for (File file : filesTemp) {
if (file.getName().endsWith("mca")) {
// RegionFile regionFile = new RegionFile(file);
files.add(file);
}
}
System.out.println("--------World loaded successfully--------");
}
public void enqueue() {
System.out.println("--------Enqueuing--------");
chunksEnqueued = 0;
try {
options.reloadConfig();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
int totalFiles = options.getSaveFolderFile().listFiles().length;
int counter = 0;
//START
//Actual enqueuing takes place here
for (File file : files) {
counter++;
System.out.println("Progress: " + counter + "/" + totalFiles + ". Total chunks enqueued: " + totalChunksEnqueued);
RegionFile regionFile = new RegionFile(file);
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
DataInputStream chunk = regionFile.getChunkDataInputStream(chunkX, chunkZ);
if (regionFile.hasChunk(chunkX, chunkZ)) {
try {
Tag root = Tag.readNamedTag(chunk);
CompoundTag level = root.getCompound("Level");
ListTag sections = level.getList("Sections");
for (int i = 0; i < sections.size(); i++) {
CompoundTag section = (CompoundTag) sections.get(i);
byte[] blocksArray = section.getByteArray("Blocks");
byte[] addsArray = section.getByteArray("Add");
byte Y = section.getByte("Y");
boolean worked = false;
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
// int realX = regionX * 32 + chunkX * 16 + x;
int realY = Y * 16 + y;
// int realZ = regionZ * 32 + chunkZ * 16 + z;
if (realY >= minY && realY <= maxY) {
// Copied from Chunk Format page.
int BlockPos = (y * 16 * 16) + (z * 16) + (x);
byte BlockID_a = blocksArray[BlockPos];
short BlockID = BlockID_a;
if (addsArray.length != 0) {
byte BlockID_b = nibble4(addsArray, BlockPos);
BlockID = (short) (BlockID_a + (BlockID_b << 8));
}
for (int block : blockIDs) {
if (BlockID == block) {
worked = true;
markSafeChunks(regionFile, chunkX, chunkZ, radius);
break;
}
}
}
if (worked)
break;
}
if (worked)
break;
}
if (worked)
break;
}
if (worked)
break;
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
try {
regionFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//END
System.out.println("Chunks enqueued this time: " + chunksEnqueued);
System.out.println("Total chunks enqueued: " + totalChunksEnqueued);
System.out.println("--------Finished enqueueing--------");
}
public void delete() {
System.out.println("--------Deleting--------");
try {
options.reloadConfig();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
int totalFiles = options.getSaveFolderFile().listFiles().length;
//START
// Deletion takes place here
for (File file : files) {
RegionFile regionFile = new RegionFile(file);
// You are now in a region file.
counter++;
System.out.println("Progress: " + counter + "/" + totalFiles);
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
if (!safeChunks.contains("" + chunkX + "_" + chunkZ) && regionFile.hasChunk(chunkX, chunkZ)) {
try {
regionFile.deleteChunk(chunkX, chunkZ);
chunksDeleted++;
} catch (IOException e1) {
e1.printStackTrace();
return;
}
}
}
}
try {
regionFile.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
//END
System.out.println("Chunks deleted: " + chunksDeleted);
System.out.println("--------Finished enqueueing--------");
}
private synchronized void markSafeChunks(RegionFile regionFile, int chunkX, int chunkZ, int radius) {
if (radius == 0)
safeChunks.add("" + chunkX + "_" + chunkZ);
else
for (int surX = chunkX - radius; surX <= chunkX + radius; surX++) {
for (int surZ = chunkZ - radius; surZ <= chunkZ + radius; surZ++) {
boolean b = surX > chunkX/32 && surX < chunkX/32 + 32;
b &= surZ > chunkZ/32 && surZ < chunkZ/32 + 32;
if (b && regionFile.hasChunk(surX, surZ) && !safeChunks.contains("" + surX + "_" + surZ)) {
safeChunks.add("" + surX + "_" + surZ);
chunksEnqueued++;
totalChunksEnqueued++;
}
}
}
}
この961天井の問題が起こっている理由を任意のアイデア?
デバッグのヘルプを求める質問( '**なぜこのコードは動作しませんか?** ')には、目的の動作、特定の問題またはエラー、およびそれを再現するのに必要な最短コード**が質問自体に含まれている必要があります**。 **明確な問題文**のない質問は他の読者には役に立たない。参照:[最小限で完全で検証可能なサンプルの作成方法](http://stackoverflow.com/help/mcve) – Biffen
コードには、HashSetへの参照はありません。また、961個の要素の後ろに追加しようとしている値がHashSetにすでに含まれているかどうかを確認してください。 – 11thdimension
@ 11thdimension **実際にはDeleterクラスのHashSetへの参照があり、追加する前にそのHashSetに値が含まれているかどうかチェックします。 – Lazini