로 표시됩니다. 소개
안녕하십니까. 나는 지금 약 2 주 동안 문제가 발생했고 은이 왜 일어나는지 알 수없는 것처럼 보입니다. 그래서, 어떤 경우입니까? 내 프로젝트 Hashet 최대 크기는 961
의
거친 설명은 내가 저장 파일의 모든 영역에 파일을 읽고,이를 확인하는 마인 크래프트 도구를 쓰고 있어요. 플레이어가 배치 한 블록이있는 경우 해당 블록이 들어있는 청크는 안전하다고 표시되고 나중에 삭제되지 않습니다. 그렇지 않으면 청크는 몇 가지 대기열이 생성되기 때문에 대기열에 포함 된 프로세스가 완료된 후 삭제됩니다. 그것은 내가 사용하고있는 HashSet의에서 961 개 요소에 도달 할 때까지
문제는
이 프로그램은 잘 실행 것으로 보인다. 해시 세트에는 문자열이 들어있어 청크가 안전하다고 표시되었는지 확인하는 데 사용됩니다. 961 개의 요소가 있으면 메모리가 부족한 것처럼 더 이상 추가 할 수없는 것처럼 동작합니다. 사실이 아니더라도 2GB의 메모리를 할당했지만 여전히 아무것도 아닙니다. 나는 많은 다른 매개 변수로 여러 번 테스트했지만 그것은 961
오류
HashSet의에 요소를 추가하는 동안, 그것은 961에서 최대 상판 및 하지보다 더 이상 추가하지에서 꼭대기 그. 2GB의 RAM으로 테스트되었지만 운이 없음.
코드
여기 내 코드입니다. 그것을 압도하지 마라, 그것은 꽤 간단하다.
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();
}
}
}
왜 961 천장의 문제가 일어나고
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++;
}
}
}
}
어떤 아이디어 Deleter
클래스?
디버깅에 도움이되는 질문 ('**이 코드가 작동하지 않는 이유는 무엇입니까?** ')에는 원하는 동작, 특정 문제 또는 오류 및 문제 자체 **를 재현하는 데 필요한 가장 짧은 코드가 포함되어야합니다. ** 명확한 문제 성명 **이없는 질문은 다른 독자에게 유용하지 않습니다. 참조 : [최소한의 완전하고 검증 가능한 예제를 만드는 방법] (http://stackoverflow.com/help/mcve). – Biffen
코드에 HashSet에 대한 참조가 없습니다. 또한 HashSet에 이미 961 개 요소 뒤에 추가하려는 값이 포함되어 있는지 확인하십시오. – 11thdimension
@ 11thdimension ** Deleter 클래스의 HashSet에 대한 참조가 ** 실제로 ** 추가 ** ** 전에 HashSet에 값이 포함되어 있는지 확인합니다 ** – Lazini