Scoped Memory Reference Question

What I think I am doing:

Getting and instance of immortal mem.

Running logic that puts an event handler, a periodic timer, and the logic for the event

handler in immortal memory (out of the GC reach). Showing the memory consumed

for the scopedA secion, and the immortal memory.

The object is to use the scoped memory for the leaky console output, ensuring that

objects created for the console output are all deallocated when the enter logic for the async handler exits.

The way I think it is set up is that the Timer, the asynceventhandler and the actual logic

for the scopedA run are all in immortal memory. When the async event is fired, the scopedA area is allocated and the System.out.println executes from there.

stack:

heap

immortalMemory ( scopeA ref, asyncEventHander, PeriodicTimer)

scopedA ( entered to make the leaky System.out.println)

immortalMemory

The original question was why does the LTMemory scopedA reference have to be

outside the run logic, while the asyncEventHandler reference passed to the Periodic timer does not. I assum that the scopedA reference is in immortal memory.

I believe that I could put the new LTMemory() call outside the run logic and then

use the same scoped memory each time, without having to suffer the time needed to create the LTMemory area each time the asyncEvent Handler runs...

publicstaticvoid main(String[] args){

System.out.println("Welcome to RTSJ");

ImmortalMemory memIm = ImmortalMemory.instance();

memIm.enter(new Runnable(){

LTMemory scopedA;

publicvoid run(){

scopedA =new LTMemory(1024,1024,new Runnable(){

publicvoid run(){

System.out.println("TimerEvent " + scopedA.memoryConsumed());

}

});

AsyncEventHandler timerEvent =new AsyncEventHandler(){

publicvoid handleAsyncEvent(){

scopedA.enter();

}

};

PeriodicTimer pt =new PeriodicTimer(

new RelativeTime(0,0),

new RelativeTime(1000,0),

timerEvent );

pt.start();

}

});

for(int i = 0; i < 20; i++){

try{

Thread.sleep(1000);

}catch(InterruptedException e){}

System.out.println(memIm.memoryConsumed());

}

}

[3555 byte] By [mgarretta] at [2007-11-27 2:45:29]
# 1

> The way I think it is set up is that the Timer, the

> asynceventhandler and the actual logic

> for the scopedA run are all in immortal memory.

Right. The LTMemory instance, then Runnable instance, the AsyncEventHandler instance and the PeriodicTimer instance are all allocated in immortal. As are the two time objects. Every "new" within that run() method occurs in Immortal memory.

> When the async event is fired, the scopedA area is

> allocated and the System.out.println executes from

> there.

The scopedA area isn't "allocated" when the event fires, it is allocated in the run() method that is executed in immortal. When the event fires and the handler is released then it enters scopedA and the println is executed from there. When that completes the scope is left and as it is no longer in use the memory for that scope will be reclaimed. So next time the event fires it will enter the scope again and find an empty scope.

> original question was why does the LTMemory scopedA

> reference have to be outside the run logic, while the

> asyncEventHandler reference passed to the Periodic timer does not.

It doesn't have to be, but if it isn't then it has to be declared final because it is being accessed by the annonymous inner class you defined for your AsyncEventHandler. That's just a rule of inner classes: they can access local variables in the enclosing scope (that's Java language syntactic scope not "scope memory"), but those local variables must be final.

> I believe that I could put the new LTMemory() call

> outside the run logic and then

> use the same scoped memory each time, without having

> to suffer the time needed to create the LTMemory area

> each time the asyncEvent Handler runs...

You could put it outside the run() logic, but it won't change anything. Your run() logic is only executed once because you only enter immortal once. So you are using the same scoped memory each time.

davidholmesa at 2007-7-12 3:13:04 > top of Java-index,Real-Time,RTSJ (Real-Time Specification for Java)...
# 2

Thanks for the quick reply!!

> The scoped area isn't "allocated" when the event

> fires, it is allocated in the run() method that is

> executed in immortal. When the event fires and the

> handler is released then it enters scopedA and the

> println is executed from there. When that completes

> the scope is left and as it is no longer in use the

> memory for that scope will be reclaimed. So next time

> the event fires it will enter the scope again and

> find an empty scope.

Time for my Java lesson.. (I am relativeley new to Java!).

memIm.enter(new Runnable(){

LTMemory scopedA;

public void run(){

scopedA = new LTMemory(1024,1024, new Runnable(){

public void run(){

System.out.println("TimerEvent " + scopedA.memoryConsumed());

}

});

Here, the Runnable instance is an anonymous class that looks

something like this:

class Anonymous implements Runnable {

LTMemory scopedA;

public void run(){

// allocate object out of Immortal Memory

scopedA = new LTMemory(1024,1024, new Runnable {

public void run(){

logic for execution from scoped memory,

Where are the byte codes for this logic?

Object allocated by new, exist in scopedA memory.

}

}

// create other instances

}

}

This first anonymous class is created in Immortal memory, and remains there with the scopedA reference, referencing the SCoped a object. This object is created in immortal memory. I would surmise here, that the actual physical memory has not been allocated, and will

be allocated each time the memory area is entered. Then when the

enter is complete, and the scopedA reference count goes to 0, the

memory is 'free' ed, with the scopedA object still sitting in Immortale

memory, for use on the next enter call.

> It doesn't have to be, but if it isn't then it has to

> be declared final because it is being accessed by the

> annonymous inner class you defined for your

> AsyncEventHandler. That's just a rule of inner

> classes: they can access local variables in the

> enclosing scope (that's Java language syntactic scope

> not "scope memory"), but those local variables must

> be final.

I might be doing something wrong but I can not seem to get it

to work inside the run method, even when declared final. I do

now undestand the difference between scopedA being referenced

inside the inner class.

>

> You could put it outside the run() logic, but it

> won't change anything. Your run() logic is only

> executed once because you only enter immortal once.

> So you are using the same scoped memory each time.

Got it!

Thanks!

Michael

mgarretta at 2007-7-12 3:13:05 > top of Java-index,Real-Time,RTSJ (Real-Time Specification for Java)...
# 3

> I would surmise here, that the actual physical memory has not been

> allocated, and will be allocated each time the memory area is entered.

Not normally. When you create a ScopedMemory object (LTMemory or VTMemory) the backing store (or at least the minimum size backing store) is usually allocated at the same time. When you enter the scope you start allocating in the backing store - if only the minimum was pre-allocated and you try to go beyond that, it will try to grow and if it fails then you'll get an OutOfMemoryError. When you exit the scope, and noone else is using it, then the backing store is marked as being empty so that the next time an enter occurs it starts allocating with an empty backing store. (Of course finalization of the objects occurs first etc).

The actual backing store will probably not be freed until the scoped memory object itself is reclaimed.

In theory an implementation could allocate and free the backing store as you surmised *but* once the scoped memory area has been constructed it has to be guaranteed that the minimum size backing store is available. That would be a difficult guarantee to make in general, so implementations tend to allocate up front.

davidholmesa at 2007-7-12 3:13:05 > top of Java-index,Real-Time,RTSJ (Real-Time Specification for Java)...
# 4

So the Physical memory is allocated upon creation of the

LT or VT object, with the minimum amount of memory specified.

Upon entry, objects created are stored in the scoped memory,

if attempted allocations, are greater than the min, more memory

will be allocated (if possible) up to the max.

Upon exit of the entry, all objects are 'deallocated' making the full

area available upon the next entry. So in my example the memory

stack looks like this:

heap <- imortal <- scopedA

ScopedA is always available to enter into, or execute in. scopedA will

only actually be 'finalized?' (deallocated) when its reference is invalid, and only if something is there to clean it up, like having it nested in another scoped area or having it on the heap. If the reference is in immortal, its there forever.

I think..

mcg

mgarretta at 2007-7-12 3:13:05 > top of Java-index,Real-Time,RTSJ (Real-Time Specification for Java)...
# 5
That pretty much sums it up - yes. :)
davidholmesa at 2007-7-12 3:13:05 > top of Java-index,Real-Time,RTSJ (Real-Time Specification for Java)...
# 6
Thanks for the help so far David, I appreciate it! I have anotherquestion in the works and will post it when I get a chance.Michael
mgarretta at 2007-7-12 3:13:05 > top of Java-index,Real-Time,RTSJ (Real-Time Specification for Java)...