Class hierarchy prolem

D

dgront

I have a class, say MyClass, that consist of a few fields in
particular of a list of other objects:

public MyClass {
int someID;
LinkedList<ManyOfThem> bigData;
}

public ManyOfThem {
// many fields inside
}

I read a file and I create MyClass object from it. My structure of
objects reflects the file format. For each file I calculate some
features:

public MyFeature {
double theFeatureValue;
MyClass source;
}

As you see, I keep the computed value and a reference to MyClass
because I need to remember MyClass.someID for some reasons.
Unfortunately Java also keeps in memory all ManyOfThem objects and
there are really many of them!

Unfortunately ManyOfThem objects are necessary to calculate MyFeature.

The problem: I read many files and for each I compute just a few
MyFeature features. Each MyFeature has a reference to MyClass. Because
MyClass keeps also a list of ManyOfThem references, 2GB RAM is not
enough to parse my all data. MyFeature data itself is very small, the
problem is how to get rid of ManyOfThem objects.

In C++ I would use destructor.... What to do in Java to forget about
ManyOfThem objects?

Can I do the following: I split MyClass into two:

public SimplerClass {
int someID;
}

public MyClass extends SimplerClass {
LinkedList<ManyOfThem> bigData;
}

And now MyFeature keeps only a reference to the simpler class.
public MyFeature {
double theFeatureValue;
SimplerClass source;
}
I guess when I set "source" field to a reference to (SimplerClass)
MyClass. It want solve my problem, will it?

But what if I set:
someFeature.source = ((SimplerClass) myClassObject).clone()

I expect that clone() method from SimplerClass will create a new
object without ManyOfThem stuff. And myClass memory will be free at
some point. Is it correct?

Do you know any simpler/other solution to my problem?

SIncerely yours,
Dominik
 
L

Lew

dgront said:
I have a class, say MyClass, that consist of a few fields in
particular of a list of other objects:

public MyClass {
int someID;
LinkedList<ManyOfThem> bigData;
}

public ManyOfThem {
// many fields inside
}

I read a file and I create MyClass object from it. My structure of
objects reflects the file format. For each file I calculate some
features:

public MyFeature {
double theFeatureValue;
MyClass source;
}

As you see, I keep the computed value and a reference to MyClass
because I need to remember MyClass.someID for some reasons.
Unfortunately Java also keeps in memory all ManyOfThem objects and
there are really many of them!

Unfortunately ManyOfThem objects are necessary to calculate MyFeature.

The problem: I read many files and for each I compute just a few
MyFeature features. Each MyFeature has a reference to MyClass. Because
MyClass keeps also a list of ManyOfThem references, 2GB RAM is not
enough to parse my all data. MyFeature data itself is very small, the
problem is how to get rid of ManyOfThem objects.

In C++ I would use destructor.... What to do in Java to forget about
ManyOfThem objects?

Make sure that there are no more references to an object and eventually the
garbage collection (GC) thread may clean it up - will clean it up if it needs
the heap.
Can I do the following: I split MyClass into two:

public SimplerClass {
int someID;
}

public MyClass extends SimplerClass {
LinkedList<ManyOfThem> bigData;
}

This will keep the reference to bigData alive whenever there's a reference to
the SimplerClass instance that happens to actually be a MyClass instance.
And now MyFeature keeps only a reference to the simpler class.
public MyFeature {
double theFeatureValue;
SimplerClass source;
}
I guess when I set "source" field to a reference to (SimplerClass)
MyClass. It want solve my problem, will it?

No - the references chain.
But what if I set:
someFeature.source = ((SimplerClass) myClassObject).clone()

I expect that clone() method from SimplerClass will create a new
object without ManyOfThem stuff. And myClass memory will be free at
some point. Is it correct?

Instance methods are polymorphic - if the object happens actually to be a
MyClass, then the MyClass clone() will operate and you will copy the reference
to the List.
Do you know any simpler/other solution to my problem?

Yes, release the MyClass instance and create a new one when you want to
"forget" the List inside the old one. Simply pointing the MyClass reference
to a different instance will do the trick, assuming it was the only reference
to the old object.

A typical example is a loop:

for ( Foo foo : foos )
{
MyClass inst = new MyClass();
inst.doSomething( foo );
}

Each time through the loop, the 'inst' variable points to a new 'MyClass' and
the previous instance is eligible for GC, assuming doSomething() doesn't
create another reference to the 'MyClass' object.

When the previous instance becomes eligible for GC, all the instances that it
referenced will be eligible for GC if there are no other references to them.
 
D

dgront

Instance methods are polymorphic - if the object happens actually to be a
MyClass, then the MyClass clone() will operate and you will copy the reference
to the List.

Ok, so will it be OK, if I add createSimpleClass() method to MyClass?
The it will be:

List<MyFeature> results = ...
for(Foo foo: foos) {
MyClass inst = new MyClass();
inst.doSomething( foo );
MyFeature f = inst.getFeature();
f.source = inst.createSimpleClass(); // Makes a deep copy of
SimpleClass data; no ManyOfThem objects are cloned
list.add(f);
}
Does my list still keeps also ManyOfThem objects?
 
M

Mark Space

dgront said:
I have a class, say MyClass, that consist of a few fields in
particular of a list of other objects:

public MyClass {
int someID;
LinkedList<ManyOfThem> bigData;
}

public ManyOfThem {
// many fields inside
}

I read a file and I create MyClass object from it. My structure of
objects reflects the file format. For each file I calculate some
features:

public MyFeature {
double theFeatureValue;
MyClass source;
}


Maybe I missed something, but why not just set bigData to null when you
are done? If all you need is theFeatureValue, after you calculate it,
just empty out the LinkedList.

public MyClass {
int someID;
List<ManyOfThem> bigData;

public void removeAll() {
bigData = null;
}
}

That leaves you with a MyClass for the reference in MyFeature, and the
int someID still set. The List will be garbage collected when the JVM
is ready. If it makes difference in user experience, you can ask that
the gc clean up objects with a call to System.gc();

Or maybe Lew already said that and I just missed it.
 
L

Lew

Mark said:
Maybe I missed something, but why not just set bigData to null when you
are done? If all you need is theFeatureValue, after you calculate it,
just empty out the LinkedList.

public MyClass {
int someID;
List<ManyOfThem> bigData;

public void removeAll() {
bigData = null;
}
}

That leaves you with a MyClass for the reference in MyFeature, and the
int someID still set. The List will be garbage collected when the JVM
is ready. If it makes difference in user experience, you can ask that
the gc clean up objects with a call to System.gc();

Or maybe Lew already said that and I just missed it.

I didn't. I never recommend setting to null as a way of clearing object
references, except in the few cases where it's necessary for the algorithm or
scope anyway, and it is my firm conclusion that System.gc() is a useless call
that shouldn't even be in the library.

However, that said, in this particular instance it looks like setting bigData
to null is one way of dealing with the matter. Another is invoking clear() on
the List. The latter is often (not always) a better solution, in that it ties
the lifetime of the List object to the lifetime of the MyClass instance.

Side note: Unless other classes in the same package need unmediated access to
instance variables, and that is vanishingly rare, one should declare instance
variables with private access.
 
D

Daniel Pitts

dgront said:
I have a class, say MyClass, that consist of a few fields in
particular of a list of other objects:

public MyClass {
int someID;
LinkedList<ManyOfThem> bigData;
}

public ManyOfThem {
// many fields inside
}

I read a file and I create MyClass object from it. My structure of
objects reflects the file format. For each file I calculate some
features:

public MyFeature {
double theFeatureValue;
MyClass source;
}

As you see, I keep the computed value and a reference to MyClass
because I need to remember MyClass.someID for some reasons.
Unfortunately Java also keeps in memory all ManyOfThem objects and
there are really many of them!

Unfortunately ManyOfThem objects are necessary to calculate MyFeature.

The problem: I read many files and for each I compute just a few
MyFeature features. Each MyFeature has a reference to MyClass. Because
MyClass keeps also a list of ManyOfThem references, 2GB RAM is not
enough to parse my all data. MyFeature data itself is very small, the
problem is how to get rid of ManyOfThem objects.

In C++ I would use destructor.... What to do in Java to forget about
ManyOfThem objects?

Can I do the following: I split MyClass into two:

public SimplerClass {
int someID;
}

public MyClass extends SimplerClass {
LinkedList<ManyOfThem> bigData;
}

And now MyFeature keeps only a reference to the simpler class.
public MyFeature {
double theFeatureValue;
SimplerClass source;
}
I guess when I set "source" field to a reference to (SimplerClass)
MyClass. It want solve my problem, will it?

But what if I set:
someFeature.source = ((SimplerClass) myClassObject).clone()

I expect that clone() method from SimplerClass will create a new
object without ManyOfThem stuff. And myClass memory will be free at
some point. Is it correct?

Do you know any simpler/other solution to my problem?

SIncerely yours,
Dominik

Perhaps instead of MyFeatures keeping a reference to MyClass, why not
just have the MyFeature have a someID reference itself? If that is the
ONLY thing it needs out of MyClass.
 
D

dgront

Perhaps instead of MyFeatures keeping a reference to MyClass, why not
just have the MyFeature have a someID reference itself? If that is the
ONLY thing it needs out of MyClass.
Yes, that solution I use now. I copy all ID fields (there are more
than just a single someID).

The problem is that MyClass provides some functionality for these ID
fields, e.g. print them nicely, compare them adn so on. I need that
functionality in MyFeature class. Thus if I copy all fields, I also
have to copy a code of all relevant metods, which I would like to
avoid.

D.
 
D

Daniel Pitts

dgront said:
Yes, that solution I use now. I copy all ID fields (there are more
than just a single someID).

The problem is that MyClass provides some functionality for these ID
fields, e.g. print them nicely, compare them adn so on. I need that
functionality in MyFeature class. Thus if I copy all fields, I also
have to copy a code of all relevant metods, which I would like to
avoid.

D.
Or, better yet, factor them out into there OWN class, which handles the
printing etc...
public class MyClass {
SomeId someId;
List<LargeDataStructure> largeDataStructures;
}

public class Feature {
SomeId someId;
double value;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top