TheJacksonLaboratory / Gopher

GOPHER documentation
https://thejacksonlaboratory.github.io/Gopher/
Other
1 stars 1 forks source link

Memory issues documentation #284

Closed pnrobinson closed 6 years ago

pnrobinson commented 6 years ago

THis is a bit out of date, but we should add something like this to the trouble shooting page. http://pcgen.org/autobuilds/pcgen-docs/faqpages/faqoutofmemoryandjavaissues.html

steinha commented 6 years ago

Can we catch the OutOfMemoryError and display a proper error message? On my test machine even with very simple queries, without the -Xmx option, GOPHER immediately runs out of memory and continues to display the Creating viewpoints using ... dialog.

memory

steinha commented 6 years ago

It would also be possible I think to have GOPHER detect its heap size and/or try to relaunch itself with a larger heap size...

steinha commented 6 years ago

Alternatively, we could ship GOPHER with Run_GOPHER_Unix.sh and Run_GOPHER_Win.bat scripts (similar to FABIAN) that detect if Java 8 is installed and launch GopherGui-0.5.0.jar with an appropriate heap option.

pnrobinson commented 6 years ago

I have been trying to put the viewpoint creation thread in a try catch block with this

 } catch (OutOfMemoryError ooem) {
            MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
            MemoryUsage heapMemory = memoryBean.getHeapMemoryUsage();
            MemoryUsage nonHeapMemory = memoryBean.getNonHeapMemoryUsage();
            String format = "%-15s%-15s%-15s%-15s";
            StringBuilder sb = new StringBuilder();

            sb.append(String.format(format, "COMMITTED", "INIT", "USED", "MAX")).append("\n");
            sb.append(String.format(format,
                    NumberFormat.getInstance().format(heapMemory.getCommitted()),
                    NumberFormat.getInstance().format(heapMemory.getInit()),
                    NumberFormat.getInstance().format(heapMemory.getUsed()),
                    NumberFormat.getInstance().format(heapMemory.getMax()))).append("\n");

            sb.append("NON-HEAP MEMORY").append("\n");
            sb.append(String.format(format, "COMMITTED", "INIT", "USED", "MAX")).append("\n");
            sb.append(String.format(format,
                    NumberFormat.getInstance().format(heapMemory.getCommitted()),
                    NumberFormat.getInstance().format(heapMemory.getInit()),
                    NumberFormat.getInstance().format(heapMemory.getUsed()),
                    NumberFormat.getInstance().format(heapMemory.getMax()))).append("\n");
            ooem.printStackTrace();
            System.err.println(sb.toString());
        }

but it is not possible to cast an OutOfMemoryError to an Exception (for good reasons). It might be possible to have GOPHER check the alloted memory with getCommitted() and to issue a warning if it is not enough (before the user tries to run createViewpoints -- everything else does not require that much memory).

pnrobinson commented 6 years ago

@steinha @hansenp I am having some difficulty catching the Error when I deliberately run Gopher with low memory. I have adding this to GopherMainPresenter (line 1199)

task.setOnFailed(eh -> {
            if (eh.getSource() instanceof OutOfMemoryError) {
                PopupFactory.displayMessage("Error",
                        "Out of memory error--see online documentation for how to increase memory"
                        );
                return;
            } else {
                Exception exc = (Exception) eh.getSource().getException();
                PopupFactory.displayException("Error",
                        "Exception encountered while attempting to create viewpoints",
                        exc);
            }
        });

But I get this:

java.lang.ClassCastException: java.lang.OutOfMemoryError cannot be cast to java.lang.Exception

Any ideas? I will return to this probably this afternoon....

steinha commented 6 years ago

An Error is different from an Exception in Java, which is why the cast does not work, I think. A quick solution for OutOfMemoryError is below. It will likely fail with other Errors (e.g., StackOverflowError).

The Viewpoint creation window is setAlwaysOnTop(true) and can hide the error message. I close it before generating the message (window.close();).

Finally, I opted for a simple Alert message because the PopupFactory did not work properly in this situation generating only blank messages (maybe it requires more memory):

image

task.setOnFailed(eh -> {
    if (eh.getSource().getException() instanceof OutOfMemoryError) {
        window.close();
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle("Error");
        alert.setHeaderText(null);
        alert.setContentText("Out of memory error--see online documentation for how to increase memory");
        alert.showAndWait();
        return;
    } else {
        Exception exc = (Exception) eh.getSource().getException();
        ...
pnrobinson commented 6 years ago

Thanks -- I implemented this and also added some documentation to the RTD.

steinha commented 6 years ago

@pnrobinson, FYI – This is what the error message looks like on Windows in the current commit: image

pnrobinson commented 6 years ago

Also on linux. The dialog is not showing text, but the title should be sufficient....