2

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;
}
Artiom
  • 81
  • 12
  • Would you mind posting the code that calls writeDir()? I suspect that somehow you are modifying one (or more) of those for-each lists while going through the loop. But I can't verify that suspicion without seeing where/how that method is called. – ouflak Sep 16 '15 at 07:18
  • Yeah i can do that :) sec – Artiom Sep 16 '15 at 07:19
  • Also consider replacing {site.trim() + "/" + s + "/" + detectionList.trim(); } constructions to `StringBuilder` use. To clear StringBuilder after every iteration call `stringBuilderInstance.setLength(0)`. It will significantly reduce the amount of allocated objects at runtime. –  Sep 16 '15 at 08:32
  • Thanks for advice I will definitely do that. Thanks for reminding my that stringbuilder exists :) – Artiom Sep 16 '15 at 16:01

2 Answers2

3

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.

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Good catch. Just put pathArray.clear() at the end of createDirTest to verify that. – ouflak Sep 16 '15 at 07:28
  • So iv tested it. The issue is still present. Althou eden space drops but allocated space still growing till ~800MB are reached. Seens that gc doesnt want to deal with it – Artiom Sep 16 '15 at 07:42
  • @Artiom What happens when it reaches 800MB? Does it die? – Andreas Sep 16 '15 at 07:43
  • No, it just stays at 800mb. My mac has 8gb and all of it usually is used. I have added an image to visualize situation. Maybe there is a problem how i invoke this method ?? – Artiom Sep 16 '15 at 07:51
  • I solved the problem of allocation. The partion problem was described in your answer but the main problem was defined in the action listener. On every click there was new Object created. So need to get rid of new = in there and problem is solved – Artiom Sep 16 '15 at 08:13
0

After realizing that clicking start button created new Object's WriteFile writeFile = new WriteFile(...) , GetFileCount getFileCount = new GetFileCount(...) and XMLSaxLogic stax = new XMLSaxLogic(...) i have moved the creation of thouse object elsewhere(Therer where it will be createn only one!).

Now there is no memory problem and it doesnt go over 150MB even clicking button continuously. Everything looks normal. But i'm sure there still are some referencing problems in the code but thanks to debuging main problem is gone :)

Lesson learned: Avoid creating too much Objects too offten ^^

Big thanks to @Andreas and @ouflak !!

Artiom
  • 81
  • 12