Bug 572512 Memory mapped files for parsing storage
Unload some indexes for garbage collection
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=572512
Change-Id: If810728c8f6d5945df20eb89a845300f080a0456
diff --git a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/GarbageCleaner.java b/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/GarbageCleaner.java
index 082a5c4..9f01b0d 100644
--- a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/GarbageCleaner.java
+++ b/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/GarbageCleaner.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2020 SAP AG and others.
+ * Copyright (c) 2008, 2021 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
* Contributors:
* SAP AG - initial API and implementation
* Netflix (Jason Koch) - refactors for increased performance and concurrency
+ * Andrew Johnson (IBM) - release some indexes for GC
*******************************************************************************/
package org.eclipse.mat.parser.internal;
@@ -22,6 +23,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -32,6 +34,7 @@
import org.eclipse.mat.collect.BitField;
import org.eclipse.mat.collect.HashMapIntObject;
import org.eclipse.mat.collect.IteratorInt;
+import org.eclipse.mat.collect.IteratorLong;
import org.eclipse.mat.parser.index.IIndexReader.IOne2LongIndex;
import org.eclipse.mat.parser.index.IIndexReader.IOne2ManyIndex;
import org.eclipse.mat.parser.index.IIndexReader.IOne2OneIndex;
@@ -76,9 +79,53 @@
int newNoOfObjects = 0;
int[] newRoots = idx.gcRoots.getAllKeys();
+ IOne2LongIndex identifiersOld = idx.identifiers;
+ File tempIndexFile = Index.IDENTIFIER.getFile(idx.snapshotInfo.getPrefix()+"temp."); //$NON-NLS-1$
+ listener.subTask(MessageUtil.format(Messages.GarbageCleaner_Writing, tempIndexFile.getAbsolutePath()));
+ idx.identifiers = new LongIndexStreamer().writeTo(tempIndexFile, new IteratorLong() {
+ int i = 0;
+ @Override
+ public boolean hasNext()
+ {
+ return i < identifiersOld.size();
+ }
+
+ @Override
+ public long next()
+ {
+ if (hasNext())
+ return identifiersOld.get(i++);
+ throw new NoSuchElementException();
+ }
+ });
+ identifiersOld.close();
+ identifiersOld.delete();
IOne2LongIndex identifiers = idx.identifiers;
+ identifiers.unload();
IOne2ManyIndex preOutbound = idx.outbound;
+ IOne2OneIndex object2classIdOld = idx.object2classId;
+ tempIndexFile = Index.O2CLASS.getFile(idx.snapshotInfo.getPrefix()+"temp."); //$NON-NLS-1$
+ listener.subTask(MessageUtil.format(Messages.GarbageCleaner_Writing, tempIndexFile.getAbsolutePath()));
+ idx.object2classId = new IntIndexStreamer().writeTo(tempIndexFile, new IteratorInt() {
+ int i = 0;
+ @Override
+ public boolean hasNext()
+ {
+ return i < object2classIdOld.size();
+ }
+
+ @Override
+ public int next()
+ {
+ if (hasNext())
+ return object2classIdOld.get(i++);
+ throw new NoSuchElementException();
+ }
+ });
+ object2classIdOld.close();
+ object2classIdOld.delete();
IOne2OneIndex object2classId = idx.object2classId;
+ object2classId.unload();
HashMapIntObject<ClassImpl> classesById = idx.classesById;
/*
@@ -147,7 +194,6 @@
// create re-index map
final int[] map = new int[oldNoOfObjects];
- final long[] id2a = new long[newNoOfObjects];
List<ClassImpl> classes2remove = new ArrayList<ClassImpl>();
@@ -157,8 +203,7 @@
{
if (reachable[ii])
{
- map[ii] = jj;
- id2a[jj++] = identifiers.get(ii);
+ map[ii] = jj++;
}
else
{
@@ -217,10 +262,6 @@
reachable = null; // early gc...
- identifiers.close();
- identifiers.delete();
- identifiers = null;
-
if (listener.isCanceled())
throw new IProgressListener.OperationCanceledException();
listener.worked(1); // 4
@@ -253,7 +294,26 @@
File indexFile = Index.IDENTIFIER.getFile(idx.snapshotInfo.getPrefix());
listener.subTask(MessageUtil.format(Messages.GarbageCleaner_Writing, indexFile.getAbsolutePath()));
- idxManager.setReader(Index.IDENTIFIER, new LongIndexStreamer().writeTo(indexFile, id2a));
+ idxManager.setReader(Index.IDENTIFIER, new LongIndexStreamer().writeTo(indexFile, new IteratorLong() {
+ int i = 0;
+ @Override
+ public boolean hasNext()
+ {
+ while (i < map.length && map[i] == -1)
+ ++i;
+ return i < map.length;
+ }
+
+ @Override
+ public long next()
+ {
+ if (hasNext())
+ return identifiers.get(i++);
+ throw new NoSuchElementException();
+ }
+ }));
+ identifiers.close();
+ identifiers.delete();
if (listener.isCanceled())
throw new IProgressListener.OperationCanceledException();