Skip to content

Commit

Permalink
JBIDE-17866 JSF/KB memory leak
Browse files Browse the repository at this point in the history
UniquePaths cleaned at project deletion.
Resource and Java model listeners are removed at project deletion.
  • Loading branch information
scabanovich committed Jul 18, 2014
1 parent 3072ea2 commit 0899d5c
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
package org.jboss.tools.common.util;

import java.util.Hashtable;
import java.util.Iterator;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;

/**
Expand All @@ -34,7 +36,16 @@ public static UniquePaths getInstance() {

private UniquePaths() {}

public IPath intern(IPath path) {
/**
* IResource.getFullPath() and IResource.getLocation() return new object
* at each invocation. All clients that need storing resource paths,
* may obtain the single instance stored by this class.
* This significantly decreases the number of stored objects.
*
* @param path object returned by IResource.getFullPath() or IResource.getLocation()
* @return unique object equal to the given path.
*/
public synchronized IPath intern(IPath path) {
IPath result = paths.get(path);
if(result == null) {
paths.put(path, path);
Expand All @@ -43,4 +54,24 @@ public IPath intern(IPath path) {
return result;
}

/**
* When a resource is removed from workspace, the cash of stored
* paths should be cleaned from obsolete elements.
*
* @param removed
*/
public synchronized void clean(IResource removed) {
IPath fullPath = removed.getFullPath();
IPath location = removed.getLocation();
Iterator<IPath> it = paths.keySet().iterator();
while(it.hasNext()) {
IPath p = it.next();
if(fullPath.isPrefixOf(p)) {
it.remove();
} else if(location != null && location.isPrefixOf(p)) {
it.remove();
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ private synchronized void doGetAdapter() {
}

loader = null;
element = null;
this.element = null;
this.adapter = adapter;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ public void forceUpdate() {
}

public void resourceChanged(IResourceChangeEvent event) {
if(event.getType() == IResourceChangeEvent.PRE_DELETE
&& event.getResource() instanceof IProject && event.getResource().equals(EclipseResourceUtil.getProject(this))) {
ModelPlugin.getWorkspace().removeResourceChangeListener(this);
ModelPlugin.getDefault().getSaveParticipant().removeModel(getModel());
libs.destroy();
//TODO implement safe destroy.
// destroy();
return;
}
if(!isActive() || event == null || event.getDelta() == null) return;
if(!checkDelta(event.getDelta())) return;
List<IResourceDelta> fileDeltas = findFileDeltas(event.getDelta(), null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public boolean isAttributeEditable(String name) {
protected String getAbsolutePath() {
FolderImpl parent = (FolderImpl)getParent();
String p = (parent == null) ? null : parent.getAbsolutePath();
if(parent.linked.containsFile(getPathPart())) {
if(parent != null && parent.linked.containsFile(getPathPart())) {
return parent.linked.getFileByFileName(getPathPart()).getAbsolutePath();
}
return (p == null) ? null : p + XModelObjectConstants.SEPARATOR + name();
Expand Down Expand Up @@ -200,7 +200,9 @@ protected void loadChildren() {
}
}
private void loadChildren(File[] fs, IResource[] rs) {
FileSystemPeer peer = getFileSystem().getPeer();
FileSystemImpl fileSystem = getFileSystem();
if(fileSystem == null) return;
FileSystemPeer peer = fileSystem.getPeer();
for (int i = 0; i < fs.length; i++) {
_loadChild(peer, fs[i]);
}
Expand Down Expand Up @@ -340,7 +342,7 @@ public boolean update() {
updateLock++;
Map<String,File> mf = new HashMap<String,File>();
linked.clearFiles();
XModelObject fileSystem = getFileSystem();
FileSystemImpl fileSystem = getFileSystem();
if(fileSystem == null) return false;
FileSystemsImpl fsi = (FileSystemsImpl)fileSystem.getParent();
try {
Expand Down Expand Up @@ -406,9 +408,9 @@ public boolean update() {
XModelObject o = (XModelObject)mc.get(nm);
File of = getChildIOFile(o);
if(o.getFileType() == XModelObject.FOLDER) {
if(!getFileSystem().getPeer().containsDir(of)) continue;
if(!fileSystem.getPeer().containsDir(of)) continue;
} else {
if(!getFileSystem().getPeer().contains(of)) continue;
if(!fileSystem.getPeer().contains(of)) continue;
}
toRemove.put(nm, o);
io.remove();
Expand Down Expand Up @@ -591,7 +593,9 @@ private void setForceLoadProperty(XModelObject f, boolean b) {
}

protected void updateLoaded(XModelObject o, File f) throws XModelException {
FileSystemPeer peer = getFileSystem().getPeer();
FileSystemImpl fs = getFileSystem();
if(fs == null) return;
FileSystemPeer peer = fs.getPeer();
if(o instanceof FolderImpl) {
if(!o.getAttributeValue(XModelObjectConstants.ATTR_NAME).equals(f.getName())) {
o.setAttributeValue(XModelObjectConstants.ATTR_NAME, f.getName());
Expand Down Expand Up @@ -660,7 +664,9 @@ private int question(File f) {
}

public void updateChildFile(XModelObject o, File f) throws XModelException {
FileSystemPeer peer = getFileSystem().getPeer();
FileSystemImpl fs = getFileSystem();
if(fs == null) return;
FileSystemPeer peer = fs.getPeer();
if(f.isFile() && peer.contains(f) && !peer.isUpdated(f)) return;
int i = (!o.isModified()) ? 0 : question(f);
if(i < 0) return;
Expand Down Expand Up @@ -711,7 +717,9 @@ private void reload(XModelObject o, File f) throws XModelException {
}

protected boolean updateNew(String pathpart, File f, Map<String,XModelObject> toRemove) throws XModelException {
FileSystemPeer peer = getFileSystem().getPeer();
FileSystemImpl fs = getFileSystem();
if(fs == null) return false;
FileSystemPeer peer = fs.getPeer();
if(peer.contains(f) && !peer.isUpdated(f)) return false;
XModelObject c = null;
if(f.isDirectory()) {
Expand Down Expand Up @@ -759,7 +767,9 @@ private XModelObject findOldObject(String entity, Map<String,XModelObject> toRem

protected void updateRemove(XModelObject o) throws XModelException {
boolean d = (o instanceof FolderImpl);
final FileSystemPeer peer = getFileSystem().getPeer();
FileSystemImpl fs = getFileSystem();
if(fs == null) return;
final FileSystemPeer peer = fs.getPeer();
final File rf = getChildIOFile(o);
boolean c = (d && peer.containsDir(rf)) || ((!d) && peer.contains(rf));
if(!c) return;
Expand Down Expand Up @@ -792,8 +802,10 @@ public void run() {
}

public void removeChildFile(XModelObject o) {
FileSystemImpl fs = getFileSystem();
if(fs == null) return;
boolean d = (o instanceof FolderImpl);
FileSystemPeer peer = getFileSystem().getPeer();
FileSystemPeer peer = fs.getPeer();
File rf = getChildIOFile(o);
boolean c = (d && peer.containsDir(rf)) || ((!d) && peer.contains(rf));
if(!c) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public void init() {
JavaCore.addElementChangedListener(this);
}

public void destroy() {
JavaCore.removeElementChangedListener(this);
}

private IProject getProjectResource() {
return EclipseResourceUtil.getProject(object);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ protected RegularChildren createChildren() {
return new RegularChildren();
}

public void destroy() {
if(children != null && !children.isEmpty()) {
XModelObject[] h = children.getObjects();
for (XModelObject o: h) {
((XModelObjectImpl)o).destroy();
}
//TODO provide safe work at setting children to null.
children = createChildren();
}
super.destroy();
}

public boolean areChildrenOrdered() {
return children != null && children.areChildrenOrdered();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,18 @@ void setModel(XModel model) {
public XModelEntity getModelEntity() {
return entity;
}


/**
* Destroys object.
*/
public void destroy() {
//TODO provide safe work at removing model, entity etc.
// model = null;
parent = null;
// entity = null;
//
}

public void changeEntity(String name) {
if(entity.getName().equals(name)) return;
XModelEntity newEntity = entity.getMetaModel().getEntity(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import org.jboss.tools.common.model.project.ModelNature;
import org.jboss.tools.common.model.project.ModelNatureExtension;
import org.jboss.tools.common.util.FileUtils;
import org.jboss.tools.common.util.UniquePaths;
import org.jboss.tools.common.web.WebUtils;
import org.osgi.framework.Bundle;

Expand Down Expand Up @@ -1133,7 +1134,10 @@ public void resourceChanged(IResourceChangeEvent event) {
if(event.getType() == IResourceChangeEvent.PRE_DELETE) {
IResource resource = event.getResource();
IProject project = (IProject)resource.getAdapter(IProject.class);
if(project != null) models.remove(project);
if(project != null) {
models.remove(project);
UniquePaths.getInstance().clean(project);
}
}
}

Expand Down

0 comments on commit 0899d5c

Please sign in to comment.