Weishi's Engineering Blog

How's Cali treating you?


  • Home

  • Archives

  • Tags

  • Search

Binary Lifting

Posted on 2020-06-27 |

Binary Lifting

Read more »

Minimum Spanning Tree (MST)

Posted on 2020-06-27 |

Minimum Spanning Tree (MST)

Read more »

CORS, XSS and CSRF

Posted on 2019-11-15 |

Security Related Acronyms in Web Applications

Read more »

Many Ways to Write a Wrong Binary Search Algorithm

Posted on 2018-09-21 |

Binary Search Algorithm

Read more »

Markdown Reference

Posted on 2018-05-25 |

Markdown Reference

Read more »

Reference Counting in iOS vs. Garbage Collection in Android

Posted on 2017-01-05 |
Automatic Reference Counting (ARC) vs. Tracing Garbage Collection (GC)

http://softwareengineering.stackexchange.com/questions/285333/how-does-garbage-collection-compare-to-reference-counting

http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/

Automatic Reference counting or ARC, is a form of garbage collection in which objects are deallocated once there are no more references to them, i.e. no other variable refers to the object in particular. Each object, under ARC, contains a reference counter, stored as an extra field in memory, which is incremented every time you set a variable to that object (i.e. a new reference to the object is created), and is decremented every time you set a reference to the object to nil/null, or a reference goes out of scope (i.e. it is deleted when the stack unwinds), once the reference counter goes down to zero, the object takes care of deleting itself, calling the destructor and freeing the allocated memory. This approach has a significant weakness, as we shall see below.
"There's no need to worry about memory management because it's all taken care of for you by reference counting," that's actually a misconception you still do need to take care to avoid certain conditions, namely circular references, in order for ARC to function correctly. A circular reference is when an object A holds a strong reference to an object B, which itself holds a strong reference to the same object A, in this situation neither object is going to be deallocated because in order for A to be deallocated its reference counter must be decremented to zero, but at least one of those references is object B, for object B to be deallocated, its reference counter must also be decremented to 0, but at least one of those references is object A, can you see the problem? ARC solves this by allowing the programmer to give compiler hints about how different object references should be treated, there are two types of references: strong references and weak references. Strong references are, as I mentioned above, a type of reference which prolongs the life of the referenced object (increments its reference counter), weak references are a type of reference which does not prolong the life of an object (that is, it does not increment the object's reference counter), but that would mean the referenced object could get deallocated and you'd would be left with an invalid reference pointing to junk memory. In order for this situation to be avoided, the weak reference is set to a safe value (e.g. nil in Objective-C) once the object is deallocated, thus the object has an extra responsibility of keeping track of all weak references and setting them to a safe value once it deletes itself. Weak references are usually used in a child-parent object relation, the parent holds a strong reference to all it's child objects, whereas the child objects hold a weak reference to the parent, the rationale being that in most cases if you no longer care about the parent object, you most likely no longer care about the child objects either.
Tracing garbage collection (i.e. what is most often referred to as simply garbage collection) involves keeping a list of all root objects (i.e. those stored in global variables, the local variables of the main procedure, etc) and tracing which objects are reachable (marking each object encountered) from those root objects. Once the garbage collector has gone through all the objects referenced by the root objects, the GC now goes through every allocated object, if it is marked as reachable it stays in memory, if it is not marked as reachable it is deallocated, this is known as the mark-and-sweep algorithm. This has the advantage of not suffering from the circular reference problem as: if neither the mutually referenced object A and object B are referenced by any other object reachable from the root objects, neither object A nor object B are marked as reachable and are both deallocated. Tracing garbage collectors run in certain intervals pausing all threads, which can lead to inconsistent performance (sporadic pauses). The algorithm described here is a very basic description, modern GC's are usually much more advanced using an object generation system, tri-color sets etc, and also perform other tasks such as defragmentation of the program's memory space by moving the objects to a contiguous storage space, this is the reason why GC'ed languages such as C# and Java do not allow pointers. One significant weakness of tracing garbage collectors is that class destructors are no longer deterministic, that is the programmer cannot tell when an object is going to be garbage collected in-fact GC'ed languages do not even allow the programmer to specify a class destructor, thus classes can no longer be used to encapsulate the management of resources such as file handles, database connections, etc. The responsibility is left on the programmer to close open files, database connections manually, hence why languages such as Java have a finally keyword (in the try,catch block) to make sure the cleanup code is always executed before the stack unwinds, whereas in C++ (no GC) such resources are handled by a wrapper object (allocated on the stack) which acquires the resource in the constructor and releases it in the destructor, which is always called as the object is removed from the stack.
As for performance, both have performance penalties. Automatic reference counting delivers a more consistent performance, no pauses, but slows down your application as a whole as every assignment of an object to a variable, every deallocation of an object, etc, will need an associated incrementation/decrementation of the reference counter, and taking care of reassigning the weak references and calling each destructor of each object being deallocated. GC does not have the performance penalty of ARC when dealing with object references; however, it incurs pauses while it is collecting garbage (rendering unusable for real-time processing systems) and requires a large memory space in order for it to function effectively such that it is not forced to run, thus pausing execution, too often.
As you can see both have their own advantages and disadvantages, there is no clear cut ARC is better or GC is better, both are compromises.
PS: ARC also becomes problematic when objects are shared across multiple threads requiring atomic incrementation/decrementation of the reference counter, which itself presents a whole new array of complexities and problems. This should answer your question as to "why would anyone use garbage collection".
Read more »

TODO List

Posted on 2016-09-01 |
TODO

1. Reference counting in iOS vs Garbage Collection in Android
2.
syncronized key word, (monitor lock)

singleton 
volatile keyword

singleton with param
  • getInstance(Context context)
  • getInstance(null)

ENUM

unloading of class: why in android code, you shouldn't rely on static class variables.
https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.7

Read more »

Java Nested Class - (Original Post: Usage of java keyword "final" in Android)

Posted on 2016-08-15 |

Java Nested Class

class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}

1. Static Nested Class

Intuition:

Just like a top level class, nested for packaging convenience.

Constructor:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

Consequences:

    Enclosing Class Access:
         Can only direct access outer class static members. (Like any other class accessing OuterClass.java)
    Members:
         Can define both static/non-static members. (members: fields + methods.)

Usage:

//like top-level class, more power to define, less power to access
static class StaticNestedClass {
private Integer instanceField = 1;
private static String staticField = outer_static_field;
public static void staticMethod() {
String a = outer_static_field;
}
public void instanceMethod() {
String a = outer_static_field;
//String b = outer_instance_field; //ERROR: cannot reference non-static field
}
}

2. Inner Class

Intuition:

Like a instance member, "belongs to" an outer class instance.

Constructor:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Consequences:
    Enclosing Class Access:
         Direct access to all outer class members. Just like any method in outer class.
    Members:
         Can NOT define any static members. Since it is associated with an instance.

Usage:

//Like a instance member, "belongs to" an outer class instance.
class InnerClass {

private String inner_instance_field = "inner_instance_field";

public InnerClass () {}

public void get_outer_member () { //can access any outer member
String a = outer_static_field;
String b = outer_private_static_method();
String c = outer_instance_field;
inner_instance_field = "";
}

//COMPILE ERROR: no static member allowed
//public interface inner_interface {}; //an interface is an effective static member
//public static String get_static_instance_field () {}
//private static String static_field = "static_field";
}

2.1. Local Class

Intuition:

Defined inside a block (a method, a if block, a for loop). The scope of the class is its enclosing block.
A special case of inner class. Thus no static member, a rule inherited from inner class.

Constructor:

Consequences:

    Enclosing Class Access:
         Direct access to all outer class members. Just like any method in outer class.
         But for local classes in static contexts, can only refer to static members of the enclosing class. "Non-static member cannot be referenced from a static context" this rule always applies.
    Members:
         Can NOT define any static members. EVEN IF it's inside a static block.
         Only exception is for static final String/primitive. As they are stored like a constant.
A local class can have static members provided that they are constant variables.
(A constant variable is a variable of primitive type or type String that is declared
final and initialized with a compile-time constant expression.
A compile-time constant expression is typically a string or an arithmetic expression
that can be evaluated at compile time.
Note: If a primitive type or a string is defined as a constant and the value is known at
compile time, the compiler replaces the constant name everywhere in the code with its value.
This is called a compile-time constant. If the value of the constant in the outside world changes
(for example, if it is legislated that pi actually should be 3.975),
you will need to recompile any classes that use this constant to get the current value.

    Local Variable Access:
         Can access local variables or method parameters that is final.
A local class can use the local variables, method parameters, 
and even exception parameters that are in its scope,
but only if those variables or parameters are declared final.
This is because the lifetime of an instance of a local class can be
much longer than the execution of the method in which the class is defined.
For this reason, a local class must have a private internal copy of
all local variables it uses (these copies are automatically generated by the compiler).
The only way to ensure that the local variable and the private copy
are always the same is to insist that the local variable is final.
Usage:
  
{
class LocalClass {
//can access outer member
String a = outer_instance_field;
String b = outer_static_field;

//static String c = ""; //ERROR: no static allowed
//final static String d ; //ERROR: not a compile-time constant
final static String d = ""; //a constant known at compile time
}
//static class StaticLocalClass {} //ERROR: local class cannot be static, regardless where.
}

static { //this is a static context
//static class StaticLocalClass {} //ERROR: local class cannot be static, even if in static context
class LocalClass {
//can access outer member
//String a = outer_instance_field; //ERROR: non-static cannot be referenced from static context
String b = outer_static_field;

//static String c = ""; //ERROR: no static allowed
//final static String d ; //ERROR: not a compile-time constant
final static String d = ""; //a constant known at compile time
}
}

public void outer_instance_method(Object method_param) {
String outer_instance_method_local_var = "";
class LocalClass { //local class at non-static context
String f = ""; //can have non-static member

/*
A local class can have static members provided that they are constant variables.
(A constant variable is a variable of primitive type or type String that is declared
final and initialized with a compile-time constant expression.
A compile-time constant expression is typically a string or an arithmetic expression
that can be evaluated at compile time.
Note: If a primitive type or a string is defined as a constant and the value is known at
compile time, the compiler replaces the constant name everywhere in the code with its value.
This is called a compile-time constant. If the value of the constant in the outside world changes
(for example, if it is legislated that pi actually should be 3.975),
you will need to recompile any classes that use this constant to get the current value.
*/
//final static Object d = new NestedClassTest(); //ERROR: this is not a compile time constant

final static int e = 5; //need to be string or int. need to know it at compile time

String a = outer_instance_field;
String b = outer_static_field;
String c = outer_instance_method_local_var; //outer_instance_method_local_var need to be final

Object abc = method_param; //can access final method param

private void local_method() {
Object d = method_param; //can access final method param

//outer_instance_method_local_var = ""; //ERROR: need to be final
//method_param = ""; //ERROR: need to be final

outer_instance_field = ""; //no problem interact with outer class field
outer_static_field = ""; //can access static or non-static

LocalClass a = new LocalClass();
}
}

//a local class is valid only within the scope defined by its enclosing block.
//But the local class has access to outer class members.
LocalClass a = new LocalClass();
/*
A local class can use the local variables, method parameters,
and even exception parameters that are in its scope,
but only if those variables or parameters are declared final.
This is because the lifetime of an instance of a local class can be
much longer than the execution of the method in which the class is defined.
For this reason, a local class must have a private internal copy of
all local variables it uses (these copies are automatically generated by the compiler).
The only way to ensure that the local variable and the private copy
are always the same is to insist that the local variable is final.
*/
outer_static_field2 = a; //here, a local class instance outlives local method scope
a.local_method();
}

2.2. Anonymous Class

Intuition: 

 Local class without a name.

Constructor:

//implementing interface
new InterfacName () { /*class-body*/ }

//extending class
new ClassName ( [ argument-list ] ) { /*class-body*/ }
Consequences:    
    Enclosing Class Access:
         Direct access to all outer class members. Just like local class.
    Members:
         Can NOT define any static members.
         Only exception is for static final String/primitive. As they are stored like a constant.
    Local Variable Access:
         Can access local variables or method parameters that is final.
Usage:
class Executor {public static void execute(Runnable r){r.run();r.run2();}}
class BaseTracker {public void track(Object obj){}}
interface Runnable {
void run(); //abstract method
default void run2(){}; //extension method
}

class Tracker extends BaseTracker{
private String outer_class_var = "";

//anonymous class
public void track1(final Object event) {
Executor.execute(new Runnable() {
//static String a = ""; //ERROR: no static allowed
final static String b = ""; //constant OK
String c = outer_class_var; //compiler create a package-level getter for enclosing class's private variables

@Override
public void run() {
Tracker.super.track(event); //Tracker.super refers to enclosing class's super class
//super.track(event); //ERROR: cannot resolve
//BaseTracker.track(event); //ERROR: can only reference static method
}
});
}

//local class
public void track2(final Object event) {
//anonymous class translated into local class
class TrackerRunnable implements Runnable {
//@Override
public void run(){
//super need to be in a non-static context

System.out.println(this.toString()); //this refers to the TrackerRunnable instance
System.out.println(super.toString()); //super defaults to the same instance!!!

Tracker.super.track(event); //Tracker.super refers to BaseTracker
Runnable.super.run2(); //Runnable.super refers to Runnable

//super.track(event); //ERROR: cannot resolve, super refers to this
//BaseTracker.track(event); //ERROR: can only reference static method, .track() is instance method
}
}
Executor.execute(new TrackerRunnable());
}

public static void main(String... args) {
new Tracker().track2("");
}
}
Reference: Java in a Nutshell: How Inner Classes Work

TODO: final keyword:
1. class - cannot be subclassed
2. method - cannot be overridden
3. variable - cannot be assigned more than once
Java memory model: stack, heap,
synthetic copy
dp/dip 是个长度单位。
Read more »

Syntax Highlighter With Blogger

Posted on 2016-07-21 |
Read more »

Wildcard and Type Parameter - ? extends Number

Posted on 2016-07-19 |
So,
Integer subclassed Number, but List<Integer> is treated as a different class as to List<Number>. 
Thus the following "? extends" is required in

sumOfList(List<? extends Number> list)
Read more »
1 2
Weishi Zeng

Weishi Zeng

14 posts
7 tags
GitHub
© 2013 - 2025 Weishi Zeng
Powered by Jekyll
Theme - NexT.Muse