2015-09-14 2 views
0

im пытается решить mistery, почему этот метод для создания каталогов использует так много памяти (около 530 МБ PS Eden Space). После выполнения метода GC очищает бит памяти, но после этого некоторые остаются. Но выделенная память всегда остается неизменной (около 700 МБ Allocated All Pools). Кажется, что я не делать разыменования объектов :(Почему этот метод занимает столько памяти?

бы хорошо, если кто-то может дать мне несколько советов, как бороться с ним.

public void writeDir(File root, ArrayList<String> hardwareList, ArrayList<String> detectionListFormated, ArrayList<String> siteName, int depth) { 
if (depth == 1) { 
     return; 
    } 
    if (depth == 2) { 
     for (int i = 0; i < listToDestroy.size(); i++) { 
      String toBeFormated = listToDestroy.get(i); 
      String toBeTrimmed = toBeFormated.replace("ä", "ae").replace("ß", "ss").replace("ü", "ue").replace("ö", "oe").trim(); 
      String s = trimLastChar(toBeTrimmed); 
      int index = s.indexOf("_"); 
      if (s.charAt(index + 1) == this.stationNumber) { 
       if (s.contains("Manuelle Gruppe")) { 
        File subdir = new File(root, s); 
        File samePath = new File(root, ""); 
        subdir.mkdir(); 
        detectionListFormated.remove(i); 
        listToDestroy.remove(i); 
        writeDir(samePath, hardwareList, detectionListFormated, siteName, depth); 

       } else if (s.contains("Automatische Gruppe")) { 
        File subdir = new File(root, s); 
        File samePath = new File(root, ""); 
        subdir.mkdir(); 
        detectionListFormated.remove(i); 
        listToDestroy.remove(i); 
        writeDir(samePath, hardwareList, detectionListFormated, siteName, depth); 
       } else if (s.contains("Abschnitt")) { 
        writeDir(root.getParentFile(), hardwareList, detectionListFormated, siteName, depth + 1); 
       } else if (s.contains("Stations-Objekt")) { 
        writeDir(root.getParentFile().getParentFile(), hardwareList, detectionListFormated, siteName, depth + 2); 
       } 
      } 
     } 
    } 
    if (depth == 3) { 
     for (int i = 0; i < listToDestroy.size(); i++) { 
      String toBeFormated = listToDestroy.get(i); 
      String toBeTrimmed = toBeFormated.replace("ä", "ae").replace("ß", "ss").replace("ü", "ue").replace("ö", "oe").trim(); 
      String s = trimLastChar(toBeTrimmed); 
      int index = s.indexOf("_"); 
      if (s.charAt(index + 1) == stationNumber) { 
       if (s.contains("Abschnitt")) { 
        File subdir = new File(root, s); 
        subdir.mkdir(); 
        detectionListFormated.remove(s); 
        listToDestroy.remove(i); 
        writeDir(subdir, hardwareList, detectionListFormated, siteName, depth - 1); 
       } else if (s.contains("Detektions-Objekt")) { 
        writeDir(root.getParentFile(), hardwareList, detectionListFormated, siteName, depth + 1); 
       } else if (s.contains("Stations-Objekt")) { 
        writeDir(root.getParentFile(), hardwareList, detectionListFormated, siteName, depth + 1); 
       } 
      } 
     } 
    } 

    if (depth == 4) { 
     for (int i = 0; i < listToDestroy.size(); i++) { 
      String toBeFormated = listToDestroy.get(i); 
      String toBeTrimmed = toBeFormated.replace("ä", "ae").replace("ß", "ss").replace("ü", "ue").replace("ö", "oe").trim(); 
      String s = trimLastChar(toBeTrimmed); 
      int index = s.indexOf("_"); 
      if (s.charAt(index + 1) == stationNumber) { 
       if (s.contains("Stations-Objekt")) { 
        File subdir = new File(root, s); 
        subdir.mkdir(); 
        listToDestroy.remove(i); 
        detectionListFormated.remove(i); 
        // if added it uses literaly no memory at allSystem.gc(); 
        writeDir(root, hardwareList, detectionListFormated, siteName, depth - 3); 
       } else if (s.contains("Detektions-Objekt")) { 
        File subdir = new File(root, s); 
        subdir.mkdir(); 
        listToDestroy.remove(i); 
        detectionListFormated.remove(i); 
        // if added it uses literaly no memory at allSystem.gc(); 
        writeDir(subdir, hardwareList, detectionListFormated, siteName, depth - 1); 
       } 
      } 
     } 
    } 
    if (depth == 5) { 
     for (String s : hardwareList) { 
      String toBeFormated = s; 
      String toBeTrimmed = toBeFormated.replace("ä", "ae").replace("ß", "ss").replace("ü", "ue").replace("ö", "oe").trim(); 
      String a = trimLastChar(toBeTrimmed); 
      File subdir = new File(root, a); 
      subdir.mkdir(); 
      this.stationNumber = a.charAt(0); 
      // if added it uses literaly no memory at allSystem.gc(); 
      writeDir(subdir, hardwareList, detectionListFormated, siteName, depth - 1); 
     } 
    } 
    if (depth == 6) { 
     for (String s : siteName) { 
      String toBeFormated = s; 
      String toBeTrimmed = toBeFormated.replace("ä", "ae").replace("ß", "ss").replace("ü", "ue").replace("ö", "oe").trim(); 
      String a = trimLastChar(toBeTrimmed); 
      File subdir = new File(root, a); 
      subdir.mkdirs(); 
      listToDestroy = new CopyOnWriteArrayList<>(detectionListFormated); 
      ArrayList<String> test = new ArrayList<>(listToDestroy); 
      // if added it uses literaly no memory at allSystem.gc(); 
      writeDir(subdir, hardwareList, test, siteName, depth - 1); 
     } 
    } 
} 
} 

Спасибо :)

+0

возможно, слишком много файлов? – nafas

+0

Создано как 220 папок. Я не думаю, что это должно быть проблемой. Я ожидаю, что он создаст n количество файлов. – Artiom

+0

Вы знаете, что использование 'CopyOnWriteArrayList' означает, что есть новая копия списка всякий раз, когда вы удаляете (или выполняете какую-либо другую операцию записи)? – RealSkeptic

ответ

0

Это правда, что, поскольку вы не делаете этого в цикле, вы будете поддерживать все, что находится в стеке ниже вас. Я не уверен, что рекурсия - главная проблема здесь. Я имею в виду, что у вас есть только 6 уровней глубины, поэтому в большинстве случаев у вас есть 6 экземпляров.

Вы решили использовать библиотеку nio, чтобы сделать это вместо старой библиотеки «io». Один из cited problems со старой библиотекой io заключается в том, что у нее проблемы с большими каталогами, напрямую связанными с обработкой ресурсов.

Это, как говорится, можно сделать итеративно с помощью петли или Stack, что также приведет к некоторой эффективности памяти. Кроме того, используйте else if в более поздних операциях if.

+0

Его изменяемая глубина меняется иногда. У него есть +, но ... также ... создание возможности для бесконечных циклов. –

1

Вы используете рекурсию. Это означает, что внутри метода вы вызываете сам метод.

Например: вы вызываете метод, затем он смотрит с инструкциями if, что это за глубина, и в условиях снова вызывает метод. Но тогда выполнение первого метода не завершено, оно просто приостанавливается по мере запуска нового вызова метода. Это создает стек вызовов методов, так сказать, вложенных. Каждый вызов будет иметь свои собственные переменные, все занимающие память .. снова и снова ... вы не должны называть метод внутри себя!

+0

Есть ли лучшая альтернатива для такого рода задач? – Artiom

+1

@Matthijs 'вы не должны вызывать метод внутри себя!' Это смелое утверждение! Рекурсия может иметь свое место. –

+0

Правда, рекурсия может иметь преимущества. Не в этом случае, он добавляет и вычитает из своей переменной ... возможно, создавая с ним бесконечный цикл. –

Смежные вопросы