< prev index next >
application/org.openjdk.jmc.flightrecorder.ui/src/main/java/org/openjdk/jmc/flightrecorder/ui/pages/ClassLoadingPage.java
Print this page
@@ -30,14 +30,20 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.openjdk.jmc.flightrecorder.ui.pages;
+
+import static org.openjdk.jmc.common.item.ItemQueryBuilder.fromWhere;
+
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.resource.ImageDescriptor;
@@ -48,14 +54,15 @@
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
-
+import org.openjdk.jmc.common.IMCClassLoader;
import org.openjdk.jmc.common.IState;
import org.openjdk.jmc.common.IWritableState;
import org.openjdk.jmc.common.item.Aggregators;
+import org.openjdk.jmc.common.item.IAggregator;
import org.openjdk.jmc.common.item.IAttribute;
import org.openjdk.jmc.common.item.IItemCollection;
import org.openjdk.jmc.common.item.IItemFilter;
import org.openjdk.jmc.common.item.ItemFilters;
import org.openjdk.jmc.common.item.RangeMatchPolicy;
@@ -129,10 +136,12 @@
private static final IItemFilter TABLE_FILTER = ItemFilters.or(JdkQueries.CLASS_LOAD.getFilter(),
JdkQueries.CLASS_UNLOAD.getFilter());
private static final ItemHistogramBuilder CLASSLOADER_HISTOGRAM = new ItemHistogramBuilder();
private static final ItemListBuilder CLASS_LOADING_LIST = new ItemListBuilder();
private static final ItemListBuilder CLASS_UNLOADING_LIST = new ItemListBuilder();
+ private static final ItemListBuilder CLASS_DEFINE_LIST = new ItemListBuilder();
+ private static final ItemListBuilder CLASS_LOADER_STATISTICS_LIST = new ItemListBuilder();
private static final Map<String, Boolean> LEGEND_ITEMS = new LinkedHashMap<>();
private static final String LOADED_COUNT = "loadedCount"; //$NON-NLS-1$
private static final String UNLOADED_COUNT = "unloadedCount"; //$NON-NLS-1$
private static final String CLASS_LOAD = "classLoad"; //$NON-NLS-1$
private static final String CLASS_UNLOAD = "classUnload"; //$NON-NLS-1$
@@ -152,15 +161,31 @@
CLASS_LOADING_LIST.addColumn(JdkAttributes.CLASS_INITIATING_CLASSLOADER);
CLASS_LOADING_LIST.addColumn(JfrAttributes.START_TIME);
CLASS_LOADING_LIST.addColumn(JfrAttributes.DURATION);
CLASS_LOADING_LIST.addColumn(JfrAttributes.END_TIME);
CLASS_LOADING_LIST.addColumn(JfrAttributes.EVENT_THREAD);
+
CLASS_UNLOADING_LIST.addColumn(JfrAttributes.EVENT_TIMESTAMP);
CLASS_UNLOADING_LIST.addColumn(JfrAttributes.EVENT_THREAD);
CLASS_UNLOADING_LIST.addColumn(JdkAttributes.CLASS_UNLOADED);
CLASS_UNLOADING_LIST.addColumn(JdkAttributes.CLASS_DEFINING_CLASSLOADER);
+ CLASS_DEFINE_LIST.addColumn(JfrAttributes.START_TIME);
+ CLASS_DEFINE_LIST.addColumn(JdkAttributes.CLASS_DEFINING_CLASSLOADER);
+ CLASS_DEFINE_LIST.addColumn(JdkAttributes.CLASS_DEFINED);
+ CLASS_DEFINE_LIST.addColumn(JfrAttributes.EVENT_THREAD);
+
+ CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.ANONYMOUS_BLOCK_SIZE);
+ CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.ANONYMOUS_CHUNK_SIZE);
+ CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.ANONYMOUS_CLASS_COUNT);
+ CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.BLOCK_SIZE);
+ CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.CHUNK_SIZE);
+ CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.CLASS_COUNT);
+ CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.CLASS_LOADER_DATA);
+ CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.PARENT_CLASSLOADER);
+ CLASS_LOADER_STATISTICS_LIST.addColumn(JdkAttributes.CLASSLOADER);
+ CLASS_LOADER_STATISTICS_LIST.addColumn(JfrAttributes.START_TIME);
// FIXME: Need to make a label provider for this
// FIXME: Want to have this in the same order
LEGEND_ITEMS.put(JdkAttributes.CLASSLOADER_LOADED_COUNT.getIdentifier(), Boolean.TRUE);
LEGEND_ITEMS.put(JdkAttributes.CLASSLOADER_UNLOADED_COUNT.getIdentifier(), Boolean.FALSE);
@@ -171,12 +196,16 @@
private class ClassLoadingUi implements IPageUI {
private final ChartCanvas classLoadingChart;
private final ItemList classLoadingTable;
private final ItemList classUnloadingTable;
+ private final ItemList classDefineTable;
+ private final ItemList classLoaderStatisticsTable;
private FilterComponent classLoadingFilter;
private FilterComponent classUnloadingFilter;
+ private FilterComponent classDefineFilter;
+ private FilterComponent classLoaderStatisticsFilter;
private final SashForm sash;
private final IPageContainer pageContainer;
private IItemCollection selectionItems;
private ItemHistogram classloaderHistogram;
private FilterComponent classloaderHistogramFilter;
@@ -190,10 +219,11 @@
.of(JdkAttributes.CLASSLOADER_LOADED_COUNT, JdkAttributes.CLASSLOADER_UNLOADED_COUNT)
.map(a -> DataPageToolkit.createAttributeCheckAction(a, b -> updateChart()));
private final List<IAction> allChartSeriesActions = Stream
.concat(Stream.of(classLoadAction, classUnloadAction), statsActions).collect(Collectors.toList());
private CTabFolder tabFolder;
+ private CTabFolder classloaderFolder;
private XYChart chart;
private IRange<IQuantity> timeRange;
private FlavorSelector flavorSelector;
ClassLoadingUi(Composite parent, FormToolkit toolkit, IPageContainer pageContainer, IState state) {
@@ -218,11 +248,13 @@
DataPageToolkit.setChart(classLoadingChart, chart, pageContainer::showSelection, this::onChartSelection);
SelectionStoreActionToolkit.addSelectionStoreRangeActions(pageContainer.getSelectionStore(), chart,
JfrAttributes.LIFETIME, Messages.ClassLoadingPage_CLASS_LOADING_TIMELINE_SELECTION,
classLoadingChart.getContextMenu());
- classloaderHistogram = CLASSLOADER_HISTOGRAM.buildWithoutBorder(sash,
+ classloaderFolder = new CTabFolder(sash, SWT.NONE);
+
+ classloaderHistogram = CLASSLOADER_HISTOGRAM.buildWithoutBorder(classloaderFolder,
JdkAttributes.CLASS_DEFINING_CLASSLOADER, TableSettings.forState(state.getChild(HISTOGRAM)));
classloaderHistogramFilter = FilterComponent.createFilterComponent(classloaderHistogram, null,
getDataSource().getItems().apply(JdkFilters.CLASS_LOAD_OR_UNLOAD),
pageContainer.getSelectionStore()::getSelections, this::onHistogramFilterChange);
classloaderHistogram.getManager().getViewer().addSelectionChangedListener(
@@ -234,13 +266,42 @@
classloaderHistogram, Messages.ClassLoadingPage_CLASS_LOADING_HISTOGRAM_SELECTION,
classLoaderHistogramMm);
classLoaderHistogramMm.add(classloaderHistogramFilter.getShowFilterAction());
classLoaderHistogramMm.add(classloaderHistogramFilter.getShowSearchAction());
classloaderHistogramFilter.loadState(state.getChild(HISTOGRAM_FILTER));
+ DataPageToolkit.addTabItem(classloaderFolder, classloaderHistogramFilter.getComponent(),
+ Messages.ClassLoadingPage_CLASS_LOADER_TAB);
ItemHistogramWithInput.chain(classloaderHistogram, this::updateTables);
+ classLoaderStatisticsTable = CLASS_LOADER_STATISTICS_LIST.buildWithoutBorder(classloaderFolder,
+ TableSettings.forState(state.getChild(CLASS_LOADER_STATISTICS_TABLE)));
+ classLoaderStatisticsTable.getManager().getViewer().addSelectionChangedListener(e -> {
+ // The standard aggregators will skip the null classloader, so we need to do this manually.
+ IItemCollection selection = ItemCollectionToolkit.build(classLoaderStatisticsTable.getSelection().get());
+ Stream<IMCClassLoader> stream = ItemCollectionToolkit.values(selection, JdkAttributes.CLASSLOADER).get().distinct();
+ Set<IMCClassLoader> selected = stream.collect(Collectors.toSet());
+ IItemFilter selectionFilter = ItemFilters.and(ItemFilters.or(JdkFilters.CLASS_LOAD_OR_UNLOAD,
+ JdkFilters.CLASS_DEFINE), ItemFilters.memberOf(JdkAttributes.CLASS_DEFINING_CLASSLOADER, selected));
+ IItemCollection filteredItems = getDataSource().getItems().apply(selectionFilter);
+ pageContainer.showSelection(filteredItems);
+ updateTables(filteredItems);
+ });
+ classLoaderStatisticsFilter = FilterComponent.createFilterComponent(classLoaderStatisticsTable, null,
+ getDataSource().getItems().apply(JdkFilters.CLASS_LOADER_STATISTICS),
+ pageContainer.getSelectionStore()::getSelections, this::onClassLoaderStatisticsFilterChange);
+ MCContextMenuManager classLoaderStatisticsTableMm = MCContextMenuManager
+ .create(classLoaderStatisticsTable.getManager().getViewer().getControl());
+ ColumnMenusFactory.addDefaultMenus(classLoaderStatisticsTable.getManager(), classLoaderStatisticsTableMm);
+ SelectionStoreActionToolkit.addSelectionStoreActions(pageContainer.getSelectionStore(), classLoaderStatisticsTable,
+ Messages.ClassLoadingPage_CLASS_LOADER_STATISTICS_LIST_SELECTION, classLoaderStatisticsTableMm);
+ classLoaderStatisticsTableMm.add(classLoaderStatisticsFilter.getShowFilterAction());
+ classLoaderStatisticsTableMm.add(classLoaderStatisticsFilter.getShowSearchAction());
+ classLoaderStatisticsFilter.loadState(state.getChild(CLASS_LOADER_STATISTICS_FILTER));
+ DataPageToolkit.addTabItem(classloaderFolder, classLoaderStatisticsFilter.getComponent(),
+ Messages.ClassLoadingPage_CLASS_LOADER_STATISTICS_TAB_TITLE);
+
tabFolder = new CTabFolder(sash, SWT.NONE);
classLoadingTable = CLASS_LOADING_LIST.buildWithoutBorder(tabFolder,
TableSettings.forState(state.getChild(CLASS_LOADING_TABLE)));
classLoadingTable.getManager().getViewer().addSelectionChangedListener(e -> pageContainer
@@ -257,10 +318,28 @@
classLoadingTableMm.add(classLoadingFilter.getShowSearchAction());
classLoadingFilter.loadState(state.getChild(CLASS_LOADING_FILTER));
DataPageToolkit.addTabItem(tabFolder, classLoadingFilter.getComponent(),
Messages.ClassLoadingPage_CLASS_LOADING_TAB_TITLE);
+ classDefineTable = CLASS_DEFINE_LIST.buildWithoutBorder(tabFolder,
+ TableSettings.forState(state.getChild(CLASS_DEFINE_TABLE)));
+ classDefineTable.getManager().getViewer().addSelectionChangedListener(e -> pageContainer
+ .showSelection(ItemCollectionToolkit.build(classDefineTable.getSelection().get())));
+ classDefineFilter = FilterComponent.createFilterComponent(classDefineTable, null,
+ getDataSource().getItems().apply(JdkFilters.CLASS_DEFINE),
+ pageContainer.getSelectionStore()::getSelections, this::onClassDefineFilterChange);
+ MCContextMenuManager classDefineTableMm = MCContextMenuManager
+ .create(classDefineTable.getManager().getViewer().getControl());
+ ColumnMenusFactory.addDefaultMenus(classDefineTable.getManager(), classDefineTableMm);
+ SelectionStoreActionToolkit.addSelectionStoreActions(pageContainer.getSelectionStore(), classDefineTable,
+ Messages.ClassLoadingPage_CLASS_DEFINE_LIST_SELECTION, classDefineTableMm);
+ classDefineTableMm.add(classDefineFilter.getShowFilterAction());
+ classDefineTableMm.add(classDefineFilter.getShowSearchAction());
+ classDefineFilter.loadState(state.getChild(CLASS_DEFINE_FILTER));
+ DataPageToolkit.addTabItem(tabFolder, classDefineFilter.getComponent(),
+ Messages.ClassLoadingPage_CLASS_DEFINE_TAB_TITLE);
+
classUnloadingTable = CLASS_UNLOADING_LIST.buildWithoutBorder(tabFolder,
TableSettings.forState(state.getChild(CLASS_UNLOADING_TABLE)));
classUnloadingTable.getManager().getViewer().addSelectionChangedListener(e -> pageContainer
.showSelection(ItemCollectionToolkit.build(classUnloadingTable.getSelection().get())));
classUnloadingFilter = FilterComponent.createFilterComponent(classUnloadingTable, null,
@@ -276,34 +355,45 @@
classUnloadingFilter.loadState(state.getChild(CLASS_UNLOADING_FILTER));
DataPageToolkit.addTabItem(tabFolder, classUnloadingFilter.getComponent(),
Messages.ClassLoadingPage_CLASS_UNLOADING_TAB_TITLE);
tabFolder.setSelection(tabFolderIndex);
+ classloaderFolder.setSelection(tabFolderIndex);
PersistableSashForm.loadState(sash, state.getChild(SASH));
flavorSelector = FlavorSelector.itemsWithTimerange(form, TABLE_FILTER, getDataSource().getItems(),
pageContainer, this::onInputSelected, this::onShow, flavorSelectorState);
addResultActions(form);
onHistogramFilterChange(histogramFilter);
onClassLoadFilterChange(classLoadTableFilter);
onClassUnloadFilterChange(classUnloadTableFilter);
+ onClassDefineFilterChange(classDefineTableFilter);
+ onClassLoaderStatisticsFilterChange(classLoaderStatisticsTableFilter);
classloaderHistogram.getManager().setSelectionState(histogramSelection);
classLoadingTable.getManager().setSelectionState(classLoadingTableSelection);
classUnloadingTable.getManager().setSelectionState(classUnloadingTableSelection);
+ classDefineTable.getManager().setSelectionState(classDefineTableSelection);
+ classLoaderStatisticsTable.getManager().setSelectionState(classLoaderStatisticsTableSelection);
}
private void onHistogramFilterChange(IItemFilter filter) {
classloaderHistogramFilter.filterChangeHelper(filter, classloaderHistogram,
- getDataSource().getItems().apply(JdkFilters.CLASS_LOAD_OR_UNLOAD));
+ getDataSource().getItems().apply(ItemFilters.or(JdkFilters.CLASS_LOAD_OR_UNLOAD, JdkFilters.CLASS_DEFINE)));
if (classLoadingFilter != null) {
classLoadingFilter.notifyListener();
}
if (classUnloadingFilter != null) {
classUnloadingFilter.notifyListener();
}
+ if (classDefineFilter != null) {
+ classDefineFilter.notifyListener();
+ }
+ if (classLoaderStatisticsFilter != null) {
+ classLoaderStatisticsFilter.notifyListener();
+ }
histogramFilter = filter;
}
private void onClassLoadFilterChange(IItemFilter filter) {
classLoadingFilter.filterChangeHelper(filter, classLoadingTable,
@@ -315,28 +405,46 @@
classUnloadingFilter.filterChangeHelper(filter, classUnloadingTable,
getDataSource().getItems().apply(JdkFilters.CLASS_UNLOAD));
classUnloadTableFilter = filter;
}
+ private void onClassDefineFilterChange(IItemFilter filter) {
+ classDefineFilter.filterChangeHelper(filter, classDefineTable,
+ getDataSource().getItems().apply(JdkFilters.CLASS_DEFINE));
+ classDefineTableFilter = filter;
+ }
+
+ private void onClassLoaderStatisticsFilterChange(IItemFilter filter) {
+ classLoaderStatisticsFilter.filterChangeHelper(filter, classLoaderStatisticsTable,
+ getDataSource().getItems().apply(JdkFilters.CLASS_LOADER_STATISTICS));
+ classLoaderStatisticsTableFilter = filter;
+ }
+
@Override
public void saveTo(IWritableState state) {
PersistableSashForm.saveState(sash, state.createChild(SASH));
classloaderHistogram.getManager().getSettings().saveState(state.createChild(HISTOGRAM));
classLoadingTable.getManager().getSettings().saveState(state.createChild(CLASS_LOADING_TABLE));
classUnloadingTable.getManager().getSettings().saveState(state.createChild(CLASS_UNLOADING_TABLE));
+ classDefineTable.getManager().getSettings().saveState(state.createChild(CLASS_DEFINE_TABLE));
+ classLoaderStatisticsTable.getManager().getSettings().saveState(state.createChild(CLASS_LOADER_STATISTICS_TABLE));
classloaderHistogramFilter.saveState(state.createChild(HISTOGRAM_FILTER));
classLoadingFilter.saveState(state.createChild(CLASS_LOADING_FILTER));
classUnloadingFilter.saveState(state.createChild(CLASS_UNLOADING_FILTER));
+ classDefineFilter.saveState(state.createChild(CLASS_DEFINE_FILTER));
+ classLoaderStatisticsFilter.saveState(state.createChild(CLASS_LOADER_STATISTICS_FILTER));
ActionToolkit.saveCheckState(state.createChild(CHART), allChartSeriesActions.stream());
saveToLocal();
}
private void saveToLocal() {
histogramSelection = classloaderHistogram.getManager().getSelectionState();
classLoadingTableSelection = classLoadingTable.getManager().getSelectionState();
classUnloadingTableSelection = classUnloadingTable.getManager().getSelectionState();
+ classDefineTableSelection = classDefineTable.getManager().getSelectionState();
+ classLoaderStatisticsTableSelection = classLoaderStatisticsTable.getManager().getSelectionState();
tabFolderIndex = tabFolder.getSelectionIndex();
flavorSelectorState = flavorSelector.getFlavorSelectorState();
}
private void onShow(Boolean show) {
@@ -393,13 +501,15 @@
classloaderHistogram.show(items.apply(JdkFilters.CLASS_LOAD_OR_UNLOAD));
}
}
private void updateTables(IItemCollection selectedItems) {
- if (classLoadingTable != null && classUnloadingTable != null) {
+ if (classLoadingTable != null && classUnloadingTable != null && classDefineTable != null
+ && classLoaderStatisticsTable != null) {
classLoadingTable.show(selectedItems.apply(JdkQueries.CLASS_LOAD.getFilter()));
classUnloadingTable.show(selectedItems.apply(JdkQueries.CLASS_UNLOAD.getFilter()));
+ classDefineTable.show(selectedItems.apply(JdkQueries.CLASS_DEFINE.getFilter()));
}
}
private void onChartSelection(IRange<IQuantity> range) {
// FIXME: Make this depend on the legend as well? And maybe on which chart row has been selected?
@@ -415,25 +525,33 @@
private static final String SASH = "sash"; //$NON-NLS-1$
private static final String HISTOGRAM = "histogram"; //$NON-NLS-1$
private static final String HISTOGRAM_FILTER = "histogramFilter"; //$NON-NLS-1$
private static final String CLASS_LOADING_TABLE = "classLoadingTable"; //$NON-NLS-1$
private static final String CLASS_UNLOADING_TABLE = "classUnloadingTable"; //$NON-NLS-1$
+ private static final String CLASS_DEFINE_TABLE = "classDefineTable"; //$NON-NLS-1$
+ private static final String CLASS_LOADER_STATISTICS_TABLE = "classLoaderStatisticsTable"; //$NON-NLS-1$
private static final String CLASS_LOADING_FILTER = "classLoadingFilter"; //$NON-NLS-1$
private static final String CLASS_UNLOADING_FILTER = "classUnloadingFilter"; //$NON-NLS-1$
+ private static final String CLASS_DEFINE_FILTER = "classDefineFilter"; //$NON-NLS-1$
+ private static final String CLASS_LOADER_STATISTICS_FILTER = "classLoaderStatisticsFilter"; //$NON-NLS-1$
private static final String CHART = "chart"; //$NON-NLS-1$
@Override
public IPageUI display(Composite parent, FormToolkit toolkit, IPageContainer pageContainer, IState state) {
return new ClassLoadingUi(parent, toolkit, pageContainer, state);
}
private SelectionState histogramSelection;
private SelectionState classLoadingTableSelection;
private SelectionState classUnloadingTableSelection;
+ private SelectionState classDefineTableSelection;
+ private SelectionState classLoaderStatisticsTableSelection;
private IItemFilter histogramFilter;
private IItemFilter classLoadTableFilter;
private IItemFilter classUnloadTableFilter;
+ private IItemFilter classDefineTableFilter;
+ private IItemFilter classLoaderStatisticsTableFilter;
private int tabFolderIndex = 0;
private IRange<IQuantity> timelineRange;
private FlavorSelectorState flavorSelectorState;
public ClassLoadingPage(IPageDefinition dpd, StreamModel items, IPageContainer editor) {
< prev index next >