Issue #2594 added low memory warning job

UiPlugin starts and stops job
job notifies perspective manager of low memory
Viz perspective manager has default alert implementation
D2D and GFE override alert message
added memory threshold property to product files

(cherry picked from commit c63c8e2fc6 [formerly f9a8b68da5] [formerly 0076ec9aaf [formerly 4af42d405d3bf24b00c027f5dab8faf500a9e5b7]])

Conflicts:
	cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/perspective/GFEPerspectiveManager.java
	cave/com.raytheon.viz.product.awips/awips.product

Former-commit-id: 6859f8cca8 [formerly 7fb934f4782d23f1772ba32db05ed0c1c30ff6db]
Former-commit-id: 5a3c66323a
This commit is contained in:
Brian Clements 2014-01-14 13:00:00 -06:00 committed by Steve Harris
parent 9cc1eeb5c6
commit 1cd4dc7d4a
8 changed files with 263 additions and 4 deletions

View file

@ -88,6 +88,7 @@ import com.raytheon.viz.ui.statusline.FrameCountDisplay;
* 04/27/2010 mschenke Initial Creation.
* Mar 21, 2013 1638 mschenke Changed map scales not tied to d2d
* Oct 10, 2013 2104 mschenke Switched to use MapScalesManager
* Jan 14, 2014 2594 bclement added low memory notification
* </pre>
*
* @author mschenke
@ -417,4 +418,16 @@ public class D2DPerspectiveManager extends AbstractCAVEPerspectiveManager {
return new ChangeLegendModeAction(mode, rsc);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.perspectives.AbstractVizPerspectiveManager#
* getLowMemoryMessage(long)
*/
@Override
protected String getLowMemoryMessage(long availMemory) {
return super.getLowMemoryMessage(availMemory)
+ "\n\nConsider closing tabs, clearing panes, or reducing the frame count to free up memory.";
}
}

View file

@ -88,6 +88,7 @@ import com.raytheon.viz.ui.perspectives.VizPerspectiveListener;
* Oct 23, 2012 #1287 rferrel Changes for non-blocking FormattrLauncherDialog.
* Dec 09, 2013 #2367 dgilling Remove shutdown of ProcedureJob and
* SmartToolJob.
* Jan 14, 2014 2594 bclement added low memory notification
* </pre>
*
* @author randerso
@ -397,4 +398,17 @@ public class GFEPerspectiveManager extends AbstractCAVEPerspectiveManager {
super.addContextMenuItems(menuManager, container, pane);
menuManager.add(new ZoomMenuAction(container));
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.perspectives.AbstractVizPerspectiveManager#
* getLowMemoryMessage(long)
*/
@Override
protected String getLowMemoryMessage(long availMemory) {
return super.getLowMemoryMessage(availMemory)
+ "\n\nConsider saving Fcst grids to free up memory.";
}
}

View file

@ -31,6 +31,7 @@
-Dlogback.configurationFile=logback-viz-core.xml
-Dlogback.statusListenerClass=com.raytheon.uf.common.status.logback.UFLogbackInternalStatusListener
-Dthrift.stream.maxsize=200
-Dviz.memory.warn.threshold=98
-Djava.util.Arrays.useLegacyMergeSort=true</vmArgs>
<vmArgsLin>-Xmx1280M</vmArgsLin>
<vmArgsWin>-Dfile.encoding=UTF-8 -Xmx768M</vmArgsWin>

View file

@ -26,7 +26,8 @@
-Dcom.sun.management.jmxremote.ssl=false
-Dlogback.configurationFile=logback-viz-core-developer.xml
-Dlogback.statusListenerClass=com.raytheon.uf.common.status.logback.UFLogbackInternalStatusListener
-Dthrift.stream.maxsize=200</vmArgs>
-Dthrift.stream.maxsize=200
-Dviz.memory.warn.threshold=99</vmArgs>
<vmArgsWin>-Dfile.encoding=UTF-8</vmArgsWin>
</launcherArgs>

View file

@ -20,6 +20,7 @@
package com.raytheon.viz.ui;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
@ -28,6 +29,7 @@ import com.raytheon.uf.common.localization.exception.LocalizationException;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.localization.HierarchicalPreferenceStore;
import com.raytheon.viz.ui.jobs.MemoryMonitorJob;
import com.raytheon.viz.ui.panes.DrawCoordinatorJob;
/**
@ -58,6 +60,8 @@ public class UiPlugin extends AbstractUIPlugin {
private HierarchicalPreferenceStore prefs;
private final Job memoryWatchJob = new MemoryMonitorJob();
/**
* The constructor.
*/
@ -70,6 +74,9 @@ public class UiPlugin extends AbstractUIPlugin {
*/
public void start(BundleContext context) throws Exception {
super.start(context);
memoryWatchJob.setPriority(Job.LONG);
memoryWatchJob.setSystem(true);
memoryWatchJob.schedule();
}
/**
@ -79,6 +86,7 @@ public class UiPlugin extends AbstractUIPlugin {
super.stop(context);
plugin = null;
DrawCoordinatorJob.getInstance().shutdown();
memoryWatchJob.cancel();
}
/**

View file

@ -0,0 +1,178 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.ui.jobs;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.ui.IWorkbenchWindow;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.viz.ui.VizWorkbenchManager;
import com.raytheon.viz.ui.perspectives.AbstractVizPerspectiveManager;
import com.raytheon.viz.ui.perspectives.VizPerspectiveListener;
/**
* Monitors the memory usage and notifies the perspective when a configured
* threshold of memory usage is reached
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 14, 2014 2594 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class MemoryMonitorJob extends Job {
private static final IUFStatusHandler log = UFStatus
.getHandler(MemoryMonitorJob.class);
public static final String THRESHOLD_PROPERTY = "viz.memory.warn.threshold";
public static final String MONITOR_PERIOD_PROPERTY = "viz.memory.monitor.period";
private static final int DEFAULT_THRESHOLD = 95; // 95% memory usage
private static final long DEFAULT_PERIOD = 10 * 1000; // ten seconds
private final double threshold;
private final long period;
private boolean notified = false;
/**
* Default constructor, get configuration from system properties
*/
public MemoryMonitorJob() {
this("Low Memory Monitor", Integer.getInteger(THRESHOLD_PROPERTY,
DEFAULT_THRESHOLD), Long.getLong(MONITOR_PERIOD_PROPERTY,
DEFAULT_PERIOD));
}
/**
* @param name
* job name
* @param threshold
* percent of memory used when notification should be triggered
* (0-100)
* @param period
* period between memory checks in milliseconds
*/
public MemoryMonitorJob(String name, int threshold, long period) {
super(name);
if (threshold < 0 || threshold > 100){
logInvalidProperty(THRESHOLD_PROPERTY,
"Threshold value must be between 0 and 100",
DEFAULT_THRESHOLD);
this.threshold = DEFAULT_THRESHOLD;
} else {
this.threshold = threshold;
}
if (period < 0){
logInvalidProperty(MONITOR_PERIOD_PROPERTY,
"Monitor period value must be non-negative", DEFAULT_PERIOD);
this.period = DEFAULT_PERIOD;
} else {
this.period = period;
}
}
/**
* Log invalid configuration message
*
* @param property
* @param message
* @param defValue
*/
private static void logInvalidProperty(String property, String message,
Object defValue) {
String msg = "Invalid memory monitor configuration for property: "
+ property + ". " + message + ". Using default value of: "
+ defValue.toString();
log.error(msg);
}
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
long maxMemory = runtime.maxMemory();
if ((((double) usedMemory / maxMemory) * 100) > threshold) {
if (!notified) { // don't pester the user
long availMemory = maxMemory - usedMemory;
notified = notify(availMemory);
}
} else {
// fell below threshold, reset
notified = false;
}
return Status.OK_STATUS;
} finally {
schedule(period);
}
}
/**
* Notify perspective of low available memory
*
* @param availMemory
* @return true if notification was displayed
*/
private boolean notify(long availMemory) {
boolean rval = false;
IWorkbenchWindow window = VizWorkbenchManager.getInstance()
.getCurrentWindow();
VizPerspectiveListener listener = VizPerspectiveListener
.getInstance(window);
if (listener != null) {
AbstractVizPerspectiveManager manager = listener
.getActivePerspectiveManager();
rval = manager.notifyLowMemory(availMemory);
}
return rval;
}
/**
* @return the threshold
*/
public double getThreshold() {
return threshold;
}
/**
* @return the period
*/
public long getPeriod() {
return period;
}
}

View file

@ -52,8 +52,9 @@ import com.raytheon.viz.ui.editor.AbstractEditor;
import com.raytheon.viz.ui.statusline.TimeDisplay;
/**
* Abstract class for cave persepctives, solely for context activation and
* refreshing, contributes the TimeDisplay to the status line as well
* Abstract class for cave perspectives, solely for context activation and
* refreshing, contributes the TimeDisplay to the status line as well. Used for
* managing perspectives that render to the display.
*
* <pre>
*

View file

@ -31,7 +31,10 @@ import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IMemento;
@ -51,9 +54,11 @@ import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.SizeUtil;
import com.raytheon.uf.viz.core.ContextManager;
import com.raytheon.uf.viz.core.IDisplayPane;
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.procedures.Procedure;
import com.raytheon.viz.ui.VizWorkbenchManager;
@ -65,7 +70,8 @@ import com.raytheon.viz.ui.tools.AbstractModalTool;
import com.raytheon.viz.ui.tools.ModalToolManager;
/**
* Abstract perspective manager class.
* Manager for generic perspectives. Default implementation for general GUI
* interface management.
*
* <pre>
* SOFTWARE HISTORY
@ -75,6 +81,7 @@ import com.raytheon.viz.ui.tools.ModalToolManager;
* Mar 26, 2013 1799 bsteffen Fix pan/zoom when in views.
* Jun 19, 2013 2116 bsteffen Do not deactivate contexts for parts
* when closing an inactive perspective.
* Jan 14, 2014 2594 bclement added low memory notification
*
* </pre>
*
@ -603,4 +610,40 @@ public abstract class AbstractVizPerspectiveManager implements
}
}
}
/**
* Notify perspective manager when heap space is running low. Default action
* is to pop up a warning to the user. Perspectives can override the default
* behavior to take more extreme actions to reduce memory usage.
*
* @param freeMemory
* free memory available in bytes
* @return true if notification was displayed
*/
public boolean notifyLowMemory(long availMemory) {
final String msg = getLowMemoryMessage(availMemory);
final boolean[] status = new boolean[1];
VizApp.runSync(new Runnable() {
public void run() {
Display display = Display.getDefault();
status[0] = MessageDialog.open(MessageDialog.WARNING,
display.getActiveShell(), "Low Memory", msg, SWT.NONE);
}
});
return status[0];
}
/**
* Create the default low memory message to be displayed to the user
*
* @param availMemory
* free memory available in bytes
* @return
*/
protected String getLowMemoryMessage(long availMemory) {
return "This CAVE is nearing its maximum memory limit. "
+ "Performance may degrade significantly. "
+ SizeUtil.prettyByteSize(availMemory) + " available";
}
}