Search code examples
javafileloopsdirectory-structuremkdirs

What is the reason for this method to take so much memory?


im trying to debug this method but it seems that nothing works...
I suspect that in the conditional statement pathName.add() is cousing trouble. After this method is executed it takes up 50 MB executed one more time it takes up 150mb till it reaches 800mb. But all is allocated space. Why does the gc does not clean this mess ???

P.s this method created directories based on given path that have been constructen with conditional statements

P.s P.s The method writeDir(...) is called from within actionListener (When button on gui ic clicked). The button can be clicked offten

P.s P.s P.s I have tried Andreas suggestion and it worked partially. After invoking pathName.clean() eden space droped but allocated space was still growing maximum is reached.

memory snapshot

Would be interested in your opinion :) Thanks

Calling writeDir(...)

startButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
            try {
                        progress(0);
                        XMLSaxLogic stax = new XMLSaxLogic(xmlPath);

                        DetectionFilter detectionFilter = new DetectionFilter(stax.getObjets());
                        try {
                            WriteFile writeFile = new WriteFile(detectionFilter.getDetectionList());
                            writeFile.writeDir(savedDirPath, detectionFilter.getHardwareList(), stax.getSiteName());
                            progress(100);
                        } catch (Exception a) {
                            System.out.println(a.getLocalizedMessage());
                        }
                        GetFileCount getFileCount = new GetFileCount(savedDirPath, detectionFilter.getDetectionList(), combo.getSelectedIndex());

                        getFileCount.getFile(savedDirPath.getAbsoluteFile().toString());
                    } catch (Exception a) {
                        System.out.println(a.getLocalizedMessage());
                    }
}
}

writeDir(...)

   private ArrayList<String> detectList;
   private String detection = null;
   private String build = null;
   private Set<String> pathName = new LinkedHashSet<>();
   public WriteFile(ArrayList<String> detectList) {
       this.detectList = detectList;
   }
public void writeDir(File root, ArrayList<String> sevenElementList, ArrayList<String> oneElementList) {

    for (String site : oneElementList) {
        for (String s : sevenElementList) {
            int indexx = s.indexOf("_");
            int id = Character.getNumericValue(s.charAt(indexHardware - 1));

            for (String detectionList : detectList) {
                int index = detectionList.indexOf("_");
                int sId = Character.getNumericValue(detectionList.charAt(index + 1));

                if (detectionList.contains("Apple") && sId == id) {
                    detection = site.trim() + "/" + s + "/" + detectionList.trim();
                    pathName.add(format(detection));
                } else if (detectionList.contains("Banana") && sId == id) {
                    build = detection.trim() + "/" + detectionList.trim();
                    pathName.add(format(build.trim()));
                } else if (detectionList.contains("nananana") && sId == id) {
                    pathName.add(format(build.trim() + "/" + detectionList.trim()));
                } else if (detectionList.contains("Watermelone") && sId == id) {
                    pathName.add(format(build.trim() + "/" + detectionList));
                } else if (detectionList.contains("Orange") && sId == id) {
                    pathName.add(format(site.trim() + "/" + s.trim() + "/" + detectionList.trim()));
                }
            }
        }
    }
    createDirTest(pathName, root);
}
private void createDirTest(Set<String> pathArray, File root) {
    for (String s : pathArray) {
        File subdir = new File(root, s);
        subdir.mkdirs();
    }
}

private String format(String toBeFormated) {
    String toBeTrimmed = trimLastChar(toBeFormated.replace("ä", "ae").replace("ß", "ss").replace("ü", "ue").replace("ö", "oe").trim());
    return toBeTrimmed;
}

Solution

  • You are storing all the paths in a Set<String> pathName field, even though the part of the code you show only uses it as a parameter to createDirTest.

    All the memory used by the Set will not be released until you 1) clear the set, or 2) stop referencing the instance of the class in question.

    At some unspecified future point on time, the JVM GC will then reclaim the space.

    If you really need it as a field, why pass as parameter? createDirTest has access to the field. If not, remove the field, and declare a local variable.


    Update

    According to comment, the program keeps running even after 800MB has been used.

    In that case, it's just the way the JVM works. The program works without issue, and you're only perceiving that you have a problem. You don't.

    You can force a full garbage collection by calling System.gc() at the end of the actionPerformed() method, after the try statement, but only to confirm that a full GC releases all the memory used. Only for testing, don't leave the gc() call in there.

    To see the GC runs, you can add the -Xloggc:path/to/file.log or the -XX:+PrintGCDetails -XX:+PrintGCTimeStamps options when running your code. See documentation for more detail. Again, just for testing.