public class StackedMemory extends ScopedMemory
StackedMemory implements a scoped memory allocation area
and backing store management system. It is designed to allow for
safe, fragmentation-free management of scoped allocation with certain
strong guarantees provided by the virtual machine and runtime
libraries.
Each StackedMemory instance represents a single object
allocation area and additional memory associated with it in the form
of a backing store. The backing store associated with a
StackedMemory is a fixed-size memory area allocated at
or before instantiation of the StackedMemory. The
object allocation area is taken from the associated backing store,
and the backing store may be further subdivided into additional
StackedMemory allocation areas or backing stores by
instantiating additional StackedMemory objects.
When a StackedMemory is created with a backing store, the
backing store may be taken from a notional global backing store, in
which case it is effectively immortal, or it may be taken from the
enclosing StackedMemory's backing store when the scope in
which it is created is also a StackedMemory. In this
case it is returned to its enclosing scope's backing store when the
object is finalized. Implementations should return the
space occupied by backing stores taken from the global backing store
when their associated StackedMemory object is finalized.
These backing store semantics divide instances of
StackedMemory into two categories:
StackedMemory with an object allocation area
created in a new backing store, allocated either from the
global store or from a parent StackedMemory's
backing store, andStackedMemory with an object allocation area
taken directly from a parent StackedMemory's
backing store without creating a sub-store.StackedMemory object: root. A root
StackedMemory is a host StackedMemory
created with a backing store drawn directly from the global backing
store, created in an allocation context of some type other than
StackedMemory.
Creation of a StackedMemory shall fail with a
StaticOutOfMemoryError when the current
Schedulable is configured with a limit on
ScopedMemoryParameters.maxGlobalBackingStore and creation of the
root StackedMemory would exceed that limit.
Creation of a StackedMemory is subject to additional
restrictions when the current Schedulable is configured with an
explicit initial memory area of type StackedMemory. In this
case, the following rules apply.
StackedMemory will fail and
throw a StaticOutOfMemoryError regardless of
the value of the Schedulable's
ScopedMemoryParameters.maxGlobalBackingStore.StackedMemory from a current
allocation context that is not the Schedulable's
explicit initial memory area or one of its descendants in the
scope stack will fail and throw StaticOutOfMemoryError.ScopedMemoryParameters.maxInitialBackingStore
bytes may be allocated directly from the backing store of the
Schedulable's explicit initial memory area over the
lifetime of the Schedulable. Any operation that would
exceed this limit (whether by resizing the allocation area of
the explicit initial memory area or a guest area in the same
backing store, or by allocating a new StackedMemory
with the explicit initial memory area as the current allocation
context) will fail and throw a StaticOutOfMemoryError.
Allocations from a StackedMemory object allocation area
are guaranteed to run in time linear in the size of the allocation.
All memory for the backing store must be reserved at object
construction time.
StackedMemory memory areas have two additional
stacking constraints in addition to the single parent rule, designed
to enable fragmentation-free manipulation:
StackedMemory that is created when another
StackedMemory is the current allocation context
can only be entered from the same allocation context in which
it was created, and StackedMemory may not be created from
a StackedMemory that currently has another child
area that is also a guest StackedMemory, i.e.,
a StackedMemory can have at most one
direct child that is a guest StackedMemory.
The StackedMemory constructor semantics also enforce the
property that a StackedMemory may not be created from
another StackedMemory allocation context unless it is
allocated from that context's backing store as either a host or guest
area.
The backing store of a StackedMemory behaves as if any
StackedMemory object allocation areas are at the
“bottom” of the backing store, while the backing stores
for enclosed StackedMemory areas are taken from the
“top” of the backing store.
There may be an implementation-specific memory overhead for creating
a backing store of a given size. This means that creating a
StackedMemory with a backing store of exactly the
remaining available backing store of the current
StackedMemory may fail with an
javax.realtime.StaticOutOfMemoryError. This overhead must be
bounded by a constant.
| Constructor and Description |
|---|
StackedMemory(long scopeSize)
Equivalent to
StackedMemory(long, Runnable) with argument
list (scopeSize, null). |
StackedMemory(long scopeSize,
long backingSize)
Equivalent to
StackedMemory(long, long, Runnable) with argument
list (scopeSize, backingSize, null). |
StackedMemory(long scopeSize,
long backingSize,
java.lang.Runnable logic)
Creates a host
StackedMemory with an object
allocation area and backing store of the specified sizes, bound to
the specified Runnable. |
StackedMemory(long scopeSize,
java.lang.Runnable logic)
Create a guest
StackedMemory with an object
allocation area of the specified size, bound to the specified
Runnable. |
StackedMemory(SizeEstimator scopeSize)
Equivalent to
StackedMemory(long, Runnable) with argument
list (scopeSize.getEstimate(), null). |
StackedMemory(SizeEstimator scopeSize,
java.lang.Runnable logic)
Equivalent to
StackedMemory(long, Runnable) with argument
list (scopeSize.getEstimate(), runnable). |
StackedMemory(SizeEstimator scopeSize,
SizeEstimator backingSize)
Equivalent to
StackedMemory(long, long, Runnable) with argument
list (scopeSize.getEstimate(), backingSize.getEstimate(), null). |
StackedMemory(SizeEstimator scopeSize,
SizeEstimator backingSize,
java.lang.Runnable logic)
Equivalent to
StackedMemory(long, long, Runnable) with argument
list (scopeSize.getEstimate(), backingSize.getEstimate(), runnable). |
| Modifier and Type | Method and Description |
|---|---|
void |
enter()
Associates this memory area with the current
Schedulable object for the duration of the
run() method of the instance of
Runnable given in this object's constructor. |
void |
enter(java.lang.Runnable logic)
Associates this memory area with the current
Schedulable object for the duration of the
run() method of the given Runnable. |
long |
getMaximumSize()
Gets the maximum size this memory area can attain.
|
long |
hostBackingStoreConsumed()
Determines the amount of memory consumed by exisiting stacked memories
from the backing store of this stacked memory.
|
long |
hostBackingStoreRemaining()
Determines the amount of memory remaining for allocation to new
stacked memories in the backing store of this stacked memory.
|
long |
hostBackingStoreSize()
Determines the total amount of memory in the backing store of this
stacked memory.
|
void |
joinAndEnter()
In the error-free case,
joinAndEnter combines
join();enter(); such that no enter() from
another schedulable can intervene between the two method
invocations. |
void |
joinAndEnter(HighResolutionTime<?> time)
In the error-free case,
joinAndEnter combines
join();enter(); such that no enter() from
another schedulable can intervene between the two method
invocations. |
void |
joinAndEnter(java.lang.Runnable logic)
In the error-free case,
joinAndEnter combines
join(); and enter(); such that no enter()
from another schedulable can intervene between the two method
invocations. |
void |
joinAndEnter(java.lang.Runnable logic,
HighResolutionTime<?> time)
In the error-free case,
joinAndEnter combines
join();enter(); such that no enter() from
another schedulable can intervene between the two method
invocations. |
void |
resize(long scopeSize)
Changes the size of the object allocation area for this scope.
|
enter, enter, enter, enter, enter, executeInArea, executeInArea, executeInArea, executeInArea, executeInArea, executeInArea, finalize, getParent, getPortal, getReferenceCount, globalBackingStoreConsumed, globalBackingStoreRemaining, globalBackingStoreSize, join, join, joinAndEnter, joinAndEnter, joinAndEnter, joinAndEnter, joinAndEnter, joinAndEnter, joinAndEnter, joinAndEnter, joinAndEnter, joinAndEnter, newArray, newInstance, newInstance, setPortal, toString, visitNestedScopes, visitScopeRootsgetMemoryArea, mayHoldReferenceTo, mayHoldReferenceTo, memoryConsumed, memoryRemaining, newArrayInArea, sizepublic StackedMemory(long scopeSize,
long backingSize,
java.lang.Runnable logic)
StackedMemory with an object
allocation area and backing store of the specified sizes, bound to
the specified Runnable. The backing store is
allocated from the currently active memory area when it is also a
StackedMemory, and the global backing store otherwise.
The object allocation area is allocated from the backing store.scopeSize - Size of the allocation area within the backing store.backingSize - Size of the total backing store.logic - Runnable to be entered using this as its
current memory area when enter() is called.StaticIllegalArgumentException - when either
scopeSize or backingSize is less than zero,
or when scopeSize is too large to be allocated from
a backing store of size backingSize.StaticOutOfMemoryError - when there is insufficient
memory available to reserve the requested backing store.IllegalTaskStateException - when the current
Schedulable has a StackedMemory as its explicit
initial scoped memory area and that area is not on the scope stack.public StackedMemory(SizeEstimator scopeSize, SizeEstimator backingSize, java.lang.Runnable logic)
StackedMemory(long, long, Runnable) with argument
list (scopeSize.getEstimate(), backingSize.getEstimate(), runnable).scopeSize - SizeEstimator indicating the size of the object
allocation area within the backing store.backingSize - SizeEstimator indicating the size of the total
backing store.logic - Runnable to be entered using this as its
current memory area when enter() is called.StaticIllegalArgumentException - when either
scopeSize or backingSize is null,
or when scopeSize.getEstimate() is too large to be
allocated from a backing store of size
backingSize.getEstimate().StaticOutOfMemoryError - when there is insufficient
memory available to reserve the requested backing store.IllegalTaskStateException - when the current
Schedulable has a StackedMemory as its explicit
initial scoped memory area and that area is not on the scope stack.public StackedMemory(long scopeSize,
long backingSize)
StackedMemory(long, long, Runnable) with argument
list (scopeSize, backingSize, null).scopeSize - Size of the allocation area within the backing store.backingSize - Size of the total backing store.StaticIllegalArgumentException - when either
scopeSize or backingSize is less than zero,
or when scopeSize is too large to be allocated from
a backing store of size backingSize.StaticOutOfMemoryError - when there is insufficient
memory available to reserve the requested backing store.IllegalTaskStateException - when the current
Schedulable has a StackedMemory as its explicit
initial scoped memory area and that area is not on the scope stack.public StackedMemory(SizeEstimator scopeSize, SizeEstimator backingSize)
StackedMemory(long, long, Runnable) with argument
list (scopeSize.getEstimate(), backingSize.getEstimate(), null).scopeSize - SizeEstimator indicating the size of the object
allocation area within the backing store.backingSize - SizeEstimator indicating the size of the total
backing store.StaticIllegalArgumentException - when either
scopeSize or backingSize is null,
or when scopeSize.getEstimate() is too large to be
allocated from a backing store of size
backingSize.getEstimate().StaticOutOfMemoryError - when there is insufficient
memory available to reserve the requested backing store.IllegalTaskStateException - when the current
Schedulable has a StackedMemory as its explicit
initial scoped memory area and that area is not on the scope stack.public StackedMemory(long scopeSize,
java.lang.Runnable logic)
StackedMemory with an object
allocation area of the specified size, bound to the specified
Runnable. The object allocation area is drawn
from the same backing store as the parent scope's object allocation
area. The parent scope must be a StackedMemory.scopeSize - Size of the allocation area within the backing store.logic - Runnable to be entered using this as its
current memory area when enter() is called.StaticIllegalArgumentException - when the
parent memory area is not a StackedMemory.MemoryInUseException - when the parent
StackedMemory already has a child that is
also a guest StackedMemory.StaticIllegalArgumentException - when
scopeSize is less than zero.StaticOutOfMemoryError - when there is insufficient
memory available in the backing store of the parent
StackedMemory's object allocation area to reserve
the requested object allocation area.IllegalTaskStateException - when the current
Schedulable has a StackedMemory as its explicit
initial scoped memory area and that area is not on the scope stack.public StackedMemory(SizeEstimator scopeSize, java.lang.Runnable logic)
StackedMemory(long, Runnable) with argument
list (scopeSize.getEstimate(), runnable).scopeSize - SizeEstimator indicating the size of
the object allocation area within the backing store.logic - Runnable to be entered using
this as its current memory area when
enter() is called.StaticIllegalArgumentException - when the
parent memory area is not a StackedMemory.MemoryInUseException - when the parent
StackedMemory already has a child that is
also a guest StackedMemory.StaticIllegalArgumentException - when
scopeSize is null.StaticOutOfMemoryError - when there is
insufficient memory available in the backing store of the
parent StackedMemory's object allocation area to
reserve the requested object allocation area.IllegalTaskStateException - when the current
Schedulable has a StackedMemory as its explicit
initial scoped memory area and that area is not on the scope stack.public StackedMemory(long scopeSize)
StackedMemory(long, Runnable) with argument
list (scopeSize, null).scopeSize - Size of the allocation area within the backing store.StaticIllegalArgumentException - when the
parent memory area is not a StackedMemory.MemoryInUseException - when the parent
StackedMemory already has a child that is
also a guest StackedMemory.StaticIllegalArgumentException - when
scopeSize is less than zero.StaticOutOfMemoryError - when there is
insufficient memory available in the backing store of the
parent StackedMemory's object allocation area to
reserve the requested object allocation area.IllegalTaskStateException - when the current
Schedulable has a StackedMemory as its explicit
initial scoped memory area and that area is not on the scope stack.public StackedMemory(SizeEstimator scopeSize)
StackedMemory(long, Runnable) with argument
list (scopeSize.getEstimate(), null).scopeSize - SizeEstimator indicating the size of the
object allocation area within the backing store.StaticIllegalArgumentException - when the
parent memory area is not a StackedMemory.MemoryInUseException - when the parent
StackedMemory already has a child that is
also a guest StackedMemory.StaticIllegalArgumentException - when
scopeSize is null.StaticOutOfMemoryError - when there is
insufficient memory available in the backing store of the
parent StackedMemory's object allocation area to
reserve the requested object allocation area.IllegalTaskStateException - when the current
Schedulable has a StackedMemory as its explicit
initial scoped memory area and that area is not on the scope stack.public void resize(long scopeSize)
Schedulable object has this area as its current allocation
context. It may be used to grow the allocation area, or to shrink
the allocation area no smaller than the size of its current usage,
when the calling Schedulable object is the only object that
has this area on its scope stack and there are no guest
StackedMemory object allocation areas created after this
area in the same backing store but not yet finalized.scopeSize - The new allocation area size for this scope.StaticSecurityException - when the caller is
not permitted to perform the requested adjustment.StaticIllegalArgumentException - there
are additional guest StackedMemory
allocation areas after this one in the backing store.StaticOutOfMemoryError - when the remaining
backing store is insufficient for the requested adjustment,
or when the current Schedulable has a StackedMemory as its explicit initial scoped memory area
and that area is not on the scope stack.public long getMaximumSize()
resize(long) without triggering an
StaticOutOfMemoryError.public long hostBackingStoreSize()
public long hostBackingStoreRemaining()
public long hostBackingStoreConsumed()
public void enter()
Schedulable object for the duration of the
run() method of the instance of
Runnable given in this object's constructor. During
this period of execution, this memory area becomes the default
allocation context until another default allocation context is
selected.
This method may only be called from the memory area in which this scope was created.
enter in class ScopedMemoryStaticIllegalArgumentException - when the currently
active memory area is a StackedMemory and is not the
area in which this scope was created, or the current memory
area is not a StackedMemory and this
StackedMemory is not a root area.ThrowBoundaryError - Thrown when the JVM needs
to propagate an exception allocated in this scope
to (or through) the memory area of the caller. Storing a
reference to that exception would cause an
IllegalAssignmentError, so the JVM cannot
be permitted to deliver the exception. The
ThrowBoundaryError is allocated in the
current allocation context and contains information about
the exception it replaces.IllegalTaskStateException - when the execution context
is not an instance of Schedulable or
when this method is invoked during finalization of objects in
scoped memory and entering this scoped memory area would force
deletion of the execution context that triggered
finalization. This would include the scope containing the
execution context, and the scope (if any) containing the
scope containing execution context.MemoryAccessError - when caller is a schedulable that may not use the heap and
this memory area's logic value is allocated in heap memory.ScopedMemory.enter()public void enter(java.lang.Runnable logic)
Schedulable object for the duration of the
run() method of the given Runnable.
During this period of execution, this memory area becomes the
default allocation context until another default allocation
context is selected.
This method may only be called from the memory area in which this scope was created.
enter in class ScopedMemorylogic - The Runnable object whose run() method should be invoked.StaticIllegalArgumentException - when the currently
active memory area is a StackedMemory and is not the
area in which this scope was created, or the current memory
area is not a StackedMemory and this
StackedMemory is not a root area.ThrowBoundaryError - when the JVM needs
to propagate
an exception allocated in this scope to (or
through) the memory area of the caller. Storing a
reference to that exception would cause an
IllegalAssignmentError, so the JVM
cannot be permitted to deliver the exception. The
ThrowBoundaryError is allocated in the
current allocation context and contains information about the
exception it replaces.IllegalTaskStateException - when the execution context
is not an instance of Schedulable or
when this method is invoked during finalization of objects in
scoped memory and entering this scoped memory area would force
deletion of the task that triggered finalization. This
would include the scope containing the task, and the scope
(if any) containing the scope containing task.MemoryAccessErrorScopedMemory.enter(Runnable)public void joinAndEnter()
throws java.lang.InterruptedException
ScopedMemoryjoinAndEnter combines
join();enter(); such that no enter() from
another schedulable can intervene between the two method
invocations. The resulting method will wait for the reference
count on this ScopedMemory to reach zero, then enters
the ScopedMemory and executes the run
method from logic passed in the constructor. When no
instance of Runnable was passed to the memory area's
constructor, the method throws
StaticIllegalArgumentException immediately.
When multiple threads are waiting in joinAndEnter
family methods for a memory area, at most one of them will
be released each time the reference count goes to zero.
Note that although joinAndEnter guarantees that
the reference count is zero when the schedulable is released
for entry, it does not guarantee that the reference count will
remain one for any length of time. A subsequent enter
could raise the reference count to two.
joinAndEnter in class ScopedMemoryjava.lang.InterruptedException - when this schedulable is interrupted by
RealtimeThread.interrupt() or
AsynchronouslyInterruptedException.fire()
while waiting for the reference count to go to zero.public void joinAndEnter(HighResolutionTime<?> time) throws java.lang.InterruptedException
ScopedMemoryjoinAndEnter combines
join();enter(); such that no enter() from
another schedulable can intervene between the two method
invocations. The resulting method will wait for the reference count
on this ScopedMemory to reach zero, or for the current
time to reach the designated time, then enter the
ScopedMemory and execute the run method
from Runnable object passed to the constructor. When no
instance of Runnable was passed to the memory area's
constructor, the method throws
StaticIllegalArgumentException immediately.
When multiple threads are waiting in joinAndEnter
family methods for a memory area, at most one of them will
be released each time the reference count goes to zero.
Since the time is expressed as a HighResolutionTime,
this method has an accurate timer with nanosecond granularity. The
actual resolution of the timer and even the quantity it measures
depends on the clock associated with time. The delay
time may be relative or absolute. When relative, then the calling
thread is blocked for at most the amount of time given by
time, and measured by its associated clock. When
absolute, then the time delay is until the indicated value is
reached by the clock. When the given absolute time is less than or
equal to the current value of the clock, the call to
joinAndEnter behaves effectively like ScopedMemory.enter().
Note that expiration of time may cause control to
enter the memory area before its reference count has gone to zero.
joinAndEnter in class ScopedMemorytime - The time that bounds the wait.java.lang.InterruptedException - when this schedulable is interrupted by
RealtimeThread.interrupt() or
AsynchronouslyInterruptedException.fire()
while waiting for the reference count to go to zero.public void joinAndEnter(java.lang.Runnable logic)
throws java.lang.InterruptedException
ScopedMemoryjoinAndEnter combines
join(); and enter(); such that no enter()
from another schedulable can intervene between the two method
invocations. The resulting method will wait for the reference count
on this ScopedMemory to reach zero,
then enter the ScopedMemory and execute the run
method from logic
When logic is null, the method throws
StaticIllegalArgumentException immediately.
When multiple threads are waiting in joinAndEnter
family methods for a memory area, at most one of them will
be released each time the reference count goes to zero.
Note that although joinAndEnter guarantees that
the reference count is zero when the schedulable is released
for entry, it does not guarantee that the reference count will
remain one for any length of time. A subsequent enter
could raise the reference count to two.
joinAndEnter in class ScopedMemorylogic - The Runnable object which contains the
code to execute.java.lang.InterruptedException - when this schedulable is interrupted by
RealtimeThread.interrupt() or
AsynchronouslyInterruptedException.fire()
while waiting for the reference count to go to zero.public void joinAndEnter(java.lang.Runnable logic,
HighResolutionTime<?> time)
throws java.lang.InterruptedException
ScopedMemoryjoinAndEnter combines
join();enter(); such that no enter() from
another schedulable can intervene between the two method
invocations. The resulting method will wait for the reference count
on this ScopedMemory to reach zero, or for the current
time to reach the designated time, then enter the
ScopedMemory and execute the run method
from logic.
Since the time is expressed as a HighResolutionTime,
this method is an accurate timer with nanosecond granularity. The
actual resolution of the timer and even the quantity it measures
depends on the clock associated with time. The delay
time may be relative or absolute. When relative, then the delay is
the amount of time given by time, and measured by its
associated clock. When absolute, then the delay is until the
indicated value is reached by the clock. When the given absolute time
is less than or equal to the current value of the clock, the call
to joinAndEnter behaves effectively like ScopedMemory.enter(Runnable).
The method throws StaticIllegalArgumentException immediately when
logic is null.
When multiple threads are waiting in joinAndEnter
family methods for a memory area, at most one of them will
be released each time the reference count goes to zero.
Note that expiration of time may cause control to
enter the memory area before its reference count has gone to zero.
joinAndEnter in class ScopedMemorylogic - The Runnable object which contains the
code to execute.time - The time that bounds the wait.java.lang.InterruptedException - when this schedulable is interrupted by
RealtimeThread.interrupt() or
AsynchronouslyInterruptedException.fire()
while waiting for the reference count to go to zero.