Skip to content

Commit

Permalink
Resolved a memory leak on the AutoCloseConnector class. Updated the T…
Browse files Browse the repository at this point in the history
…ypeInference class to reduce memory consumption. Refactored the TextClassifier class and improved its speed.
  • Loading branch information
datumbox committed Dec 31, 2015
1 parent cd549f9 commit e1ca217
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 29 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.md
@@ -1,10 +1,13 @@
CHANGELOG CHANGELOG
========= =========


Version 0.6.1 - Build 20150526 Version 0.6.1 - Build 20151231
------------------------------ ------------------------------


- Resolving minor bugs (Unreleased Resource problem on tests). - Fixed a minor issue related to Unreleased Resources on tests.
- Resolved a memory leak on the AutoCloseConnector class. Shutdown hooks are now removed when close() is called.
- Updated the TypeInference class to reduce memory consumption.
- Refactored the TextClassifier class and improved its speed.


Version 0.6.0 - Build 20150502 Version 0.6.0 - Build 20150502
------------------------------ ------------------------------
Expand Down
1 change: 1 addition & 0 deletions TODO.txt
@@ -1,6 +1,7 @@
CODE IMPROVEMENTS CODE IMPROVEMENTS
================= =================


- Add support to MapDB 2.0.
- Improve Serialization by setting the serialVersionUID in every serializable class? - Improve Serialization by setting the serialVersionUID in every serializable class?
- Create better Exceptions and Exception messages. - Create better Exceptions and Exception messages.
- Add multithreading support. - Add multithreading support.
Expand Down
18 changes: 5 additions & 13 deletions src/main/java/com/datumbox/applications/nlp/TextClassifier.java
Expand Up @@ -154,7 +154,8 @@ public void predict(Dataset testDataset) {
//ensure db loaded //ensure db loaded
knowledgeBase.load(); knowledgeBase.load();


getPredictions(testDataset); preprocessTestDataset(testDataset);
mlmodel.predict(testDataset);
} }


/** /**
Expand Down Expand Up @@ -226,7 +227,8 @@ public BaseMLmodel.ValidationMetrics validate(Dataset testDataset) {
//ensure db loaded //ensure db loaded
knowledgeBase.load(); knowledgeBase.load();


BaseMLmodel.ValidationMetrics vm = getPredictions(testDataset); preprocessTestDataset(testDataset);
BaseMLmodel.ValidationMetrics vm = mlmodel.validate(testDataset);


return vm; return vm;
} }
Expand Down Expand Up @@ -294,7 +296,7 @@ protected void _fit(Dataset trainingDataset) {
} }
} }


private BaseMLmodel.ValidationMetrics getPredictions(Dataset testDataset) { private void preprocessTestDataset(Dataset testDataset) {
TextClassifier.TrainingParameters trainingParameters = knowledgeBase.getTrainingParameters(); TextClassifier.TrainingParameters trainingParameters = knowledgeBase.getTrainingParameters();
DatabaseConfiguration dbConf = knowledgeBase.getDbConf(); DatabaseConfiguration dbConf = knowledgeBase.getDbConf();


Expand All @@ -321,20 +323,10 @@ private BaseMLmodel.ValidationMetrics getPredictions(Dataset testDataset) {
featureSelection.transform(testDataset); featureSelection.transform(testDataset);
} }



//initialize mlmodel //initialize mlmodel
if(mlmodel==null) { if(mlmodel==null) {
mlmodel = BaseMLmodel.newInstance(trainingParameters.getMLmodelClass(), dbName, dbConf); mlmodel = BaseMLmodel.newInstance(trainingParameters.getMLmodelClass(), dbName, dbConf);
} }

//call predict of the mlmodel for the new dataset
BaseMLmodel.ValidationMetrics vm = mlmodel.validate(testDataset);

if(transformData) {
dataTransformer.denormalize(testDataset); //optional denormization
}

return vm;
} }


} }
26 changes: 17 additions & 9 deletions src/main/java/com/datumbox/common/dataobjects/TypeInference.java
Expand Up @@ -27,7 +27,6 @@ public class TypeInference {
* Internal DataTypes used by the Framework. * Internal DataTypes used by the Framework.
*/ */
public enum DataType { public enum DataType {
//NOTE: DO NOT CHANGE THE ORDER OF THE ENUMS!!!
/** /**
* Boolean/Dummy Variable. * Boolean/Dummy Variable.
* Stored as boolean. * Stored as boolean.
Expand Down Expand Up @@ -126,15 +125,24 @@ private boolean isInstance(Object v) {
* @return * @return
*/ */
public static DataType getDataType(Object v) { public static DataType getDataType(Object v) {
for(DataType dataType : DataType.values()) { //NOTE: DO NOT CHANGE THE ORDER OF THE IFS!!!
if(dataType.isInstance(v)) { if(DataType.BOOLEAN.isInstance(v)) {
return dataType; return DataType.BOOLEAN;
} }
else if(DataType.ORDINAL.isInstance(v)) {
return DataType.ORDINAL;
}
else if(DataType.NUMERICAL.isInstance(v)) {
return DataType.NUMERICAL;
}
else if(DataType.CATEGORICAL.isInstance(v)) {
return DataType.CATEGORICAL;
}
else {
//We will reach this point ONLY if the value is null.
//This is because the last enum value in the loop is Categorical which uses the Object class.
return null;
} }

//We will reach this point ONLY if the value is null.
//This is because the last enum value in the loop is Categorical which uses the Object class.
return null;
} }


/** /**
Expand Down
Expand Up @@ -16,6 +16,7 @@
package com.datumbox.common.persistentstorage; package com.datumbox.common.persistentstorage;


import com.datumbox.common.persistentstorage.interfaces.DatabaseConnector; import com.datumbox.common.persistentstorage.interfaces.DatabaseConnector;
import java.util.concurrent.atomic.AtomicBoolean;


/** /**
* Any class that inherits from the abstract AutoCloseConnector class can be used * Any class that inherits from the abstract AutoCloseConnector class can be used
Expand All @@ -27,18 +28,25 @@
*/ */
public abstract class AutoCloseConnector implements DatabaseConnector, AutoCloseable { public abstract class AutoCloseConnector implements DatabaseConnector, AutoCloseable {


private boolean isClosed = false; private final AtomicBoolean isClosed = new AtomicBoolean(false);

private Thread hook;


/** /**
* Protected Constructor which is responsible for adding the Shutdown hook. * Protected Constructor which is responsible for adding the Shutdown hook.
*/ */
protected AutoCloseConnector() { protected AutoCloseConnector() {
Runtime.getRuntime().addShutdownHook(new Thread() { hook = new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
AutoCloseConnector.this.hook = null;
if(AutoCloseConnector.this.isClosed()) {
return;
}
AutoCloseConnector.this.close(); AutoCloseConnector.this.close();
} }
}); });
Runtime.getRuntime().addShutdownHook(hook);
} }


/** /**
Expand All @@ -48,23 +56,29 @@ public void run() {
*/ */
@Override @Override
public boolean isClosed() { public boolean isClosed() {
return isClosed; return isClosed.get();
} }


/** /**
* Marks the connector as closed. * Marks the connector as closed.
*/ */
@Override @Override
public void close() { public void close() {
isClosed = true; if(isClosed() == false && hook != null) {
//remove hook to save memory
Runtime.getRuntime().removeShutdownHook(hook);
hook = null;
}
isClosed.set(true);
} }


/** /**
* Ensures the connection is not closed. * Ensures the connection is not closed.
*/ */
protected void ensureNotClosed() { protected void ensureNotClosed() {
if(isClosed) { if(isClosed()) {
throw new RuntimeException("The connector is already closed"); throw new RuntimeException("The connector is already closed");
} }
} }

} }

0 comments on commit e1ca217

Please sign in to comment.