Memory management in Mobile Java

Download Report

Transcript Memory management in Mobile Java

2. Memory Management
• Basics of memory usage in mobile devices
– Static and dynamic allocation
– Managing memory organization
• Memory management in Symbian OS
• Memory management in Mobile Java
• Summary
Mobiiliohjelmointi
Kevät 2009
1
Rationale
• Memory usage is a tangling concern in mobile
devices
– All programs use memory
– In order to reduce costs, only limited amount of memory
available in mobile devices
– Also power consumption factor exists
• Memory usage is to a great extent determined by
programmers, although used tools also have an
effect
– The fashion programs are composed is an issue
– Allocation of variables to memory is an issue
• Not an option to blame infrastructure but focus placed
on application design
Mobiiliohjelmointi
Kevät 2009
2
Dynamic allocation
• Execution stack
– Manages control flow of a thread, allocation takes
places automatically as execution advances
– Contains activation records (or stack frames); one
per method/function call
• Heap
– Unstructured pool of memory
– Must be managed by the programmer in C++;
Java VM manages this automatically
– Risk of garbaging; risk of fragmentation
• (Disk)
Mobiiliohjelmointi
Kevät 2009
3
Program and Stack
Memory
int todo {
return 1;
};
int main() {
todo();
}
return
address
todo
main
todo()
main()
source code
stack
Mobiiliohjelmointi
Kevät 2009
Program image
4
Stack and Activation Record
Previous activation record
Return address
Return value
Parameters
Activation
record
Local variables
Other information
Next activation record
Mobiiliohjelmointi
Kevät 2009
5
Example
struct Sample {
int i;
char c;
};
How to allocate to different memory locations?
Does it really matter?
Mobiiliohjelmointi
Kevät 2009
6
Sample in Memory
Stack
...
int SInStack() {
Sample s;
....
}
int SInHeap() {
Sample * s;
s = new Sample;
....
}
s.i
s.c
...
Stack
...
How about limited stack size?
Mobiiliohjelmointi
Kevät 2009
Heap
...
s
s.i
...
s.c
...
7
Content and goals
• Basics of memory usage in mobile devices
– Static and dynamic allocation
– Managing memory organization
• Memory management in Symbian OS
• Memory management in Mobile Java
• Summary
Mobiiliohjelmointi
Kevät 2009
8
Static allocation
• Simplest case (in practice usually allocated in heap, but without
programmer interventions)
• Variable is statically allocated to a certain location in the
memory
int x;
int * pointer_to_static()
{
static int y;
return & y;
}
• Restrictions regarding e.g. information hiding, etc.
Mobiiliohjelmointi
Kevät 2009
9
Stack
• Home for transient objects
– Allocation and deallocation is automatic
– No need to make an explicit operating system call
for memory
• References and sharing of data problematic
int * pointer_to_int()
{
int y;
return & y;
}
Mobiiliohjelmointi
Kevät 2009
10
Example
Running
pointer_to_int
After executing
pointer_to_int
stack
pointer
stack
pointer
pointer_to_int
activation
Calling
activation
Running other
procedure
x
...
stack
pointer
Some
other
activation
x
...
Calling
activation
Mobiiliohjelmointi
Kevät 2009
Reference
to x
...
f
...
Calling
activation
11
Heap
• Home for long-living objects
– Sharing is less problematic than with stack-based variables,
but errors can still occur (aliasing -> copy-on-write?)
– Large or global objects/data/variables that are needed in all
phases of the program
• Reference passing commonly advocated in mobile
setting
• Management of creation and deletion required
int * pointer_to_int()
{
return new int(0);
}
Mobiiliohjelmointi
Kevät 2009
12
Example
Copy
of
x
...
x
&x
x
...
Full object
in stack
...
Activation 1
&x
...
&x
...
...
Reference
in stack
Activation 2
Mobiiliohjelmointi
Kevät 2009
13
Inheritance and virtual machine
• Inheritance implies a data structure for maintaining
information needed for dynamic binding
– Virtual function table
• Virtual machine introduces yet another infrastructure
on top of a processor
– Class loader loads programs
– Execution engine acts as the scheduler, memory manager,
and interpreter
– Run-time data
Mobiiliohjelmointi
Kevät 2009
14
Virtual Function Table
class C {
int i;
char c;
virtual void v();
virtual double d();
};
C.v
code
ID
i
c
Stack/Heap
(Object instantiated
in memory)
Mobiiliohjelmointi
Kevät 2009
v-id
C.d
code
d-id
Virtual
function
table
(program
memory,
RAM)
Method
code
(program
memory,
RAM)
15
Memory Allocation: What Is
Allocated Where?
• Constants
– ROM if enabled
• Program binaries
– ROM (in-place execution; how about e.g. code encryption for
protection or upgrades?)
– RAM (additional RAM required for programs)
• Data
– RAM
– Saving to disk/flash memory? What would the user be
expecting?
Mobiiliohjelmointi
Kevät 2009
16
Content and goals
• Basics of memory usage in mobile devices
– Static and dynamic allocation
– Managing memory organization
• Memory management in Symbian OS
• Memory management in Mobile Java
• Summary
Mobiiliohjelmointi
Kevät 2009
17
Managing memory organization
• Principle:
– Use the simplest data structure that offers the
necessary operations
• Then:
– Consider linear data structures instead of
distribution (less system calls, design-time
management, monitoring option, cache, index
size)
– Consider other means of benefitting from memory
layout (some basic principles to follow)
– Consider packing
Mobiiliohjelmointi
Kevät 2009
18
Non-linear and linear data
structure
Program’s address space
Program’s address space
Cache window
Cache window
List-based data structure
Mobiiliohjelmointi
Kevät 2009
Linear data structure
19
Basic Principles
• Allocate all memory at the beginning of a
program
• Allocate memory for several items even if you
only need one
• Use standard allocation sizes
• Reuse objects
• Release early, allocate late
• Use permanent storage or ROM when
applicable
• Avoid recursion (of uncontrolled depth?)
Mobiiliohjelmointi
Kevät 2009
20
Consider packing
• Use compression with care
• Use efficient resource storage format
• Consider word alignment
struct S {
char b; // boolean
int i;
char c;
}
struct S {
char b; // boolean
char c;
int i;
}
Mobiiliohjelmointi
Kevät 2009
21
char
int
Mobiiliohjelmointi
Kevät 2009
bool
char
int
char
int
bool
bool
Packing
22
Content and goals
• Basics of memory usage in mobile devices
– Static and dynamic allocation
– Managing memory organization
• Memory management in Symbian OS
• Memory management in Mobile Java
• Summary
Mobiiliohjelmointi
Kevät 2009
23
Naming Conventions
•
•
•
•
•
•
•
•
•
•
•
•
•
Class names start with C
Kernel class names start with D
Type names start with T
Mixin class names start with M
Enumerated class names start with E
Resource names start with R
Method names start with a capital letter
Names of methods that can throw an exception end with L (or
LC)
Simple getters and setters reflect the name of the variable
Instance variable names begin with i
Argument names begin with a
Constant names begin with K
Automatic variable names begin with lower-case letters
Mobiiliohjelmointi
Kevät 2009
24
Descriptors
•
Symbian way of using strings
_L("Hello"); (depreciated except in demos and debugging)
_LIT(KHelloRom, "Hello");
// String in program binary.
TBufC<5> HelloStack(KHelloRom); // Data in thread stack.
HBufC* helloHeap = KHelloRom.AllocLC(); // Data in heap.
•
Guards against overflows
char userid[8]; // Vanilla C++
strcpy(userid, "[email protected]");
TBuf<8> userid; // Symbian
userid = _L("[email protected]");
Mobiiliohjelmointi
Kevät 2009
25
Some memory layouts
(unmodifiable)
TPtrC
iLength
12
TDesC
(modifiable)
TPtr
TPtrC
iLength
12
TDesC
(unmodifiable)
TBufC<12>
(Modifiable)
TBuf<15>
Hello, World!
iPtr
ROM, heap or stack
iMaxLength
12
TDes
iPtr
TPtr
iLength
12
iBuf
Hello, world!
TDesC
TBufC
iLength
12
TDesC
iMaxLength
15
TDes
Mobiiliohjelmointi
Kevät 2009
iBuf
Hello, world
TBuf
26
Using Descriptors
• Use descriptors rather than degenerate to Ttext*
format
• Use TDesC& for arguments
– Light-weight
– Safe (no accidential modifiction)
– Any descriptor can be passed
• Use new only with HBufC
– Reserve others from stack
• Type casting is possible
– HBufC::Des
– TPtr, TDesC::Alloc
– HBufC *
Mobiiliohjelmointi
Kevät 2009
27
Exceptions
• Trap harness rather than standard exceptions
TRAPD(error, BehaveL()); // try
if (error != KErrNone) // Exception handler
{ // catch
if (error == KErrNotSupported) {...}
if (error == KErrUnknown) {...}
}
User::Leave(KOutOfMemory); // throw
Mobiiliohjelmointi
Kevät 2009
28
Exceptions and Allocation
• All memory allocations use an overridden
version of new operator
c = new (ELeave) CMyClass();
• Corresponding method
c = new CMyClass();
if (!c) User::Leave(KOutOfMemory);
return c;
Mobiiliohjelmointi
Kevät 2009
29
Problem: What happens to automatic
heap-based variables in an exception?
Before an exception
Stack
Heap
Mobiiliohjelmointi
Kevät 2009
Memory garbaging
after an exception
Stack
Heap
30
Cleanup Stack – An Auxiliary
Data Structure
Cleanup stack enables deallocation during an exception
Stack
Heap
Mobiiliohjelmointi
Kevät 2009
Cleanup Stack
31
Using Cleanup Stack
• A programmer responsiblity
• Only for automatic variables, never for others
CMyClass * c = new CMyClass();
CleanupStack::PushL(c)
... c is used
CleanupStack::Pop(); // c
delete c;
c = 0;
• Classes derived from CBase get their destructor called, for
others only memory is deallocated
• Also other actions (e.g. CleanupStack::ClosePushL(file);)
Mobiiliohjelmointi
Kevät 2009
32
Two-Phase Construction
• Cleanup stack cannot help in the creation of objects
• Therefore:
– actual constructor should never fail, and
– problematic aspects should be executed only after a
reference to the object has been pushed to the cleanup
stack
CData * id = new (ELeave) CData(256);
CleanupStack::PushL(id);
id->ConstructL();
Mobiiliohjelmointi
Kevät 2009
33
Shorthands
CItem::NewL() {
CItem * self = new (ELeave) CItem;
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}
CItem::NewLC() {
CItem * self = new (ELeave) CItem;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
Mobiiliohjelmointi
Kevät 2009
34
Content and goals
• Basics of memory usage in mobile
devices
– Static and dynamic allocation
– Managing memory organization
• Memory management in Symbian OS
• Memory management in Mobile Java
• Summary
Mobiiliohjelmointi
Kevät 2009
35
Motivation
public void push(Object e) {
ensureCapasity(); // Check slots count
elements[size++] = e;
}
public Object pop() {
if (size == 0) throw new EmptyStackException();
return elements[--size];
}
• Ok?
Mobiiliohjelmointi
Kevät 2009
36
Object stack
size
Stack
Mobiiliohjelmointi
Kevät 2009
Objects stored in Stack
37
Leaking Abstraction
Objects stored in Vector
but not in Stack
size
Stack/Vector
Mobiiliohjelmointi
Kevät 2009
Objects stored in Stack
38
Upgrade
public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null;
return result;
}
Mobiiliohjelmointi
Kevät 2009
39
Rules of Thumb for Mobile Java
• Avoid small classes
• Avoid dependencies
• Select size when relevant and manage
vector/string usage
• Consider using array vs. using vector
• Use stringBuffer when possible
• Manage class and object structure
• Generate less garbage
• Consider obfuscation
• Handle array initialization
Mobiiliohjelmointi
Kevät 2009
40
Example 1
static final int SIZE = 2000;
private void arrayImp() {
numbers = new int[SIZE];
for (int i = 0; i < SIZE; i++) { numbers[i] = i; }
}
private void vectorImp() {
numberV = new Vector(SIZE);
for (int i = 0; i < SIZE; i++) { numberV.addElement(new Integer(i)); }
}
private void vectorImpSimple() {
numberV2 = new Vector(); // Default size
for (int i = 0; i < SIZE; i++) { numberV2.addElement(new Integer(i)); }
}
Mobiiliohjelmointi
Kevät 2009
41
Results
• ArrayImp (minimal overhead)
– Bytes: 8016
– Objects: 1
• VectorImp (integers wrapped to objects)
– Bytes: 40000
– Objects: 2002
• VectorImpSimple (failures in guessing the size)
– Bytes: 52000
– Objects: 2010
[Hartikainen: Java application and library memory consumption, TUT, 2005]
Mobiiliohjelmointi
Kevät 2009
42
Example 2
static final int AMOUNT = 100;
public void useString() {
String s = “”;
for(int i = 0; i < AMOUNT; i++) {
s = s + “a”;
}
}
public void useStringBuffer() {
String s = “”;
StringBuffer sb = new StringBuffer(AMOUNT);
for(int i = 0; i < AMOUNT; i++) {
sb = sb.append(“a”);
}
s = sb.toString();
}
Mobiiliohjelmointi
Kevät 2009
43
Results
• UseString (simplest)
– Bytes: 39000
– Objects: 450
• UseStringBuffer (optimized)
– Bytes: 304
– Objects: 5
[Hartikainen: Java application and library memory consumption, TUT, 2005]
Mobiiliohjelmointi
Kevät 2009
44
Example 3
• A sample application consisting of 14
classes was refactored into a form
where only 1 calss was used without
altering the behavior
– 14 classes: 14019
– 1 class: 7467
[Hartikainen: Java application and library memory consumption, TUT, 2005]
Mobiiliohjelmointi
Kevät 2009
45
Content and goals
• Basics of memory usage in mobile devices
– Static and dynamic allocation
– Managing memory organization
• Memory management in Symbian OS
• Memory management in Mobile Java
• Summary
Mobiiliohjelmointi
Kevät 2009
46
Summary
• Memory related considerations are a practical
necessity
– Even virtual machines require programmer to consider
allocation of variables and the use of data structures
• Design idioms and patterns have been introduced
that give general guidelines
– Preallocation and static allocation simplify memory
management
– Linear data structures offer several benefits
– Data packing as the last resort
• Mobile development platforms generally assume that
the developers are aware of the most common pitfalls
– Often not adequately documented but must be experimented
in practice!
Mobiiliohjelmointi
Kevät 2009
47