1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-19 15:05:36 +02:00

[306982] - [concurrent] DsfRunnable.finalize() method increases the cost of garbage collecting 10x

This commit is contained in:
Pawel Piech 2010-03-24 18:50:29 +00:00
parent 04709d2876
commit 1ba8d3916d
2 changed files with 57 additions and 44 deletions

View file

@ -14,7 +14,6 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.eclipse.cdt.dsf.internal.DsfPlugin; import org.eclipse.cdt.dsf.internal.DsfPlugin;
import org.eclipse.cdt.dsf.internal.LoggingUtils;
import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Platform;
/** /**
@ -181,34 +180,38 @@ public class DsfExecutable {
return true; return true;
} }
/** // Bug 306982
* Checks to see if the object was executed before being garbage collected. // Disable the use of finalize() method in DSF runnables tracing to avoid
* If not, and it's expected to have been, then output a trace message to // a performance penalty in garbage colleciton.
* that effect. //
* // /**
* @see java.lang.Object#finalize() // * Checks to see if the object was executed before being garbage collected.
*/ // * If not, and it's expected to have been, then output a trace message to
@Override // * that effect.
protected void finalize() { // *
if (DEBUG_EXECUTOR && !fSubmitted && isExecutionRequired()) { // * @see java.lang.Object#finalize()
StringBuilder traceBuilder = new StringBuilder(); // */
// @Override
// Record the time // protected void finalize() {
traceBuilder.append(DsfPlugin.getDebugTime()); // if (DEBUG_EXECUTOR && !fSubmitted && isExecutionRequired()) {
traceBuilder.append(' '); // StringBuilder traceBuilder = new StringBuilder();
//
final String refstr = LoggingUtils.toString(this, false); // // Record the time
traceBuilder.append("DSF executable was never executed: " + refstr); //$NON-NLS-1$ // traceBuilder.append(DsfPlugin.getDebugTime());
final String tostr = LoggingUtils.trimTrailingNewlines(this.toString()); // traceBuilder.append(' ');
if (!tostr.equals(refstr)) { //
traceBuilder.append(" ["); //$NON-NLS-1$ // final String refstr = LoggingUtils.toString(this, false);
traceBuilder.append(tostr); // traceBuilder.append("DSF executable was never executed: " + refstr); //$NON-NLS-1$
traceBuilder.append(']'); // final String tostr = LoggingUtils.trimTrailingNewlines(this.toString());
} // if (!tostr.equals(refstr)) {
traceBuilder.append("\nCreated at:\n"); //$NON-NLS-1$ // traceBuilder.append(" ["); //$NON-NLS-1$
traceBuilder.append(fCreatedAt); // traceBuilder.append(tostr);
// traceBuilder.append(']');
DsfPlugin.debug(traceBuilder.toString()); // }
} // traceBuilder.append("\nCreated at:\n"); //$NON-NLS-1$
} // traceBuilder.append(fCreatedAt);
//
// DsfPlugin.debug(traceBuilder.toString());
// }
// }
} }

View file

@ -10,12 +10,13 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.concurrent; package org.eclipse.cdt.dsf.concurrent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.internal.DsfPlugin; import org.eclipse.cdt.dsf.internal.DsfPlugin;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
@ -101,7 +102,7 @@ public class RequestMonitor extends DsfExecutable {
*/ */
private final RequestMonitor fParentRequestMonitor; private final RequestMonitor fParentRequestMonitor;
private ListenerList fCancelListeners; private List<ICanceledListener> fCancelListeners;
/** /**
* Status * Status
@ -110,6 +111,8 @@ public class RequestMonitor extends DsfExecutable {
private boolean fCanceled = false; private boolean fCanceled = false;
private boolean fDone = false; private boolean fDone = false;
private final ICanceledListener fCanceledListener;
/** /**
* This field is never read by any code; its purpose is strictly to assist * This field is never read by any code; its purpose is strictly to assist
* developers debug DPF code. Developer can select this field in the * developers debug DPF code. Developer can select this field in the
@ -144,12 +147,15 @@ public class RequestMonitor extends DsfExecutable {
// this request monitor will automatically be canceled when the parent // this request monitor will automatically be canceled when the parent
// is canceled. // is canceled.
if (fParentRequestMonitor != null) { if (fParentRequestMonitor != null) {
fParentRequestMonitor.addCancelListener( fCanceledListener = new ICanceledListener() {
new ICanceledListener() {
public void requestCanceled(RequestMonitor rm) { public void requestCanceled(RequestMonitor rm) {
cancel(); cancel();
} }
}); };
fParentRequestMonitor.addCancelListener(fCanceledListener);
} else {
fCanceledListener = null;
} }
if (DEBUG_MONITORS) { if (DEBUG_MONITORS) {
@ -197,13 +203,13 @@ public class RequestMonitor extends DsfExecutable {
* </p> * </p>
*/ */
public void cancel() { public void cancel() {
Object[] listeners = null; ICanceledListener[] listeners = null;
synchronized (this) { synchronized (this) {
// Check to make sure the request monitor wasn't previously canceled. // Check to make sure the request monitor wasn't previously canceled.
if (!fCanceled) { if (!fCanceled) {
fCanceled = true; fCanceled = true;
if (fCancelListeners != null) { if (fCancelListeners != null) {
listeners = fCancelListeners.getListeners(); listeners = fCancelListeners.toArray(new ICanceledListener[fCancelListeners.size()]);
} }
} }
} }
@ -211,8 +217,8 @@ public class RequestMonitor extends DsfExecutable {
// Call the listeners outside of a synchronized section to reduce the // Call the listeners outside of a synchronized section to reduce the
// risk of deadlocks. // risk of deadlocks.
if (listeners != null) { if (listeners != null) {
for (Object listener : listeners) { for (ICanceledListener listener : listeners) {
((ICanceledListener)listener).requestCanceled(this); listener.requestCanceled(this);
} }
} }
} }
@ -237,7 +243,7 @@ public class RequestMonitor extends DsfExecutable {
*/ */
public synchronized void addCancelListener(ICanceledListener listener) { public synchronized void addCancelListener(ICanceledListener listener) {
if (fCancelListeners == null) { if (fCancelListeners == null) {
fCancelListeners = new ListenerList(); fCancelListeners = new ArrayList<ICanceledListener>(1);
} }
fCancelListeners.add(listener); fCancelListeners.add(listener);
} }
@ -275,6 +281,10 @@ public class RequestMonitor extends DsfExecutable {
// causes a memory leak. // causes a memory leak.
fCancelListeners = null; fCancelListeners = null;
if (fParentRequestMonitor != null) {
fParentRequestMonitor.removeCancelListener(fCanceledListener);
}
try { try {
fExecutor.execute(new DsfRunnable() { fExecutor.execute(new DsfRunnable() {
public void run() { public void run() {