3overhead@creating a java stackframe]jvm #DQH

  • additional assembly instruction to prevent stack overflow… https://pangin.pro/posts/stack-overflow-handling mentions 3 “bang” instructions for each java method, except some small leaf methods
  • safepoint polling, just before popping the stackframe
  • (If the function call receives more than 6 arguments ) put first 6 args in register and the remaining args in stack. The ‘mov’ in stack involves more instructions than registers. The subsequent retrieval from stack is likely L1 cache, slower than register read.

local variables captured in nested class #Dropcopy

If a (implicitly final) local variable [1] is captured inside a nested class, where is the variable saved?

https://stackoverflow.com/questions/43414316/where-is-stored-captured-variable-in-java explains that the anonymous or local class instance has an implicit field to hold the captured variable !

[1] local variable can be an arg passed into the enclosing function. Could a primitive type or a reference type i.e. heapy thingy

The java compiler secretly adds this hidden field. Without this field, a captured primitive would be lost and a captured heapy would be unreachable when the local variable goes out of scope.

A few hours later, when the nested class instance need to access this data, it would have to rely on the hidden field.

 

lambda^anon class instance ] java

A java lambda expression is used very much like an instance of an anonymous class. However, http://tutorials.jenkov.com/java/lambda-expressions.html#lambda-expressions-vs-anonymous-interface-implementations pointed out one interesting difference:

The anonymous instance in the example has a field named. A lambda expression cannot have such fields. A lambda expression is thus said to be stateless.

value-based type as mutex #Optional.java

Value-based type is a new concept in java. Optional.java is the only important example I know, so I will use it as illustration.

One of the main ideas about value types is the lack of object identity (or perhaps their identity is detectable only to the underlying implementation i.e. JVM not Java applications). In such a world, how could we tell whether variables aa and bb “really” are the same or different?

Q: why avoid locking on value-based objects?
%%A: locking is based on identity. See why avoid locking on boxed Integers
A: https://stackoverflow.com/questions/34049186/why-not-lock-on-a-value-based-class

Side note — compared to java, c++ has a smaller community and collective brain power so discussions are more limited.

Y avoid us`boxed Integer as mutex

https://stackoverflow.com/questions/34049186/why-not-lock-on-a-value-based-class section on “UPDATE – 2019/05/18” has a great illustration

Auto-boxing of “33” usually produces distinct objects each time, but could also produce the same object repeatedly. Compiler has the leeway to optimize, just as in c++.

Remember: locking is based on object identity.

##java heap allocation+!explicit q[new]

Most of these are java compiler tricks. Here are a few java heap allocations without explicit q[new]

  • (pre-runtime) enum instance instantiation — probably at class-loading time
    • P62 [[java precisely]]
  • String myStr = “string1”; // see string pool blogpost
    • P11 [[java precisely]]
    • NOT anonymous temp object like in c++
  • “string1” + “str2” — is same as myStr.concat(..). So a method can often new up an object like this.
    • P10/11 [[java precisely]]
  • boxing
  • (most tricky) array initialization
    • int[] days ={31,28,31/* instantiates the array on heap */};
    • most tricky
    • P17 [[java precisely]] has examples
    • P16 [[java precisely]] also shows an alternative syntax “new int[]”

identityHashCode,minimum object size,relocation by JGC

https://srvaroa.github.io/jvm/java/openjdk/biased-locking/2017/01/30/hashCode.html offers a few “halo” knowledge pearls

  • every single java Object must always give an idHashcode on-demand, even if its host class has hashCode() method overridden to return a hard-coded 55.
    • hashcode() doesn’t overshadow idHashcode
  • The “contract” says an object’s idHashcode number must never [2] change, in the face of object relocations. So it’s not really computed based on address. Once someone requests the idHashCode number (like 4049040490), this number must be retained somewhere in object, as per the “contract”. It is retained in the 12-byte object header. (8-byte for a 32-bit JVM)
    • Therefore, the idHashcode contributes to the minimum size of java objects.
  • contrary to common belief, the idHashcode can clash between two objects, so idHashcode is a misnomer, more “hashcode” and not “identity”. https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6321873 explains there are insufficient integer values given the maximum object count.
  • Note anyone can call the hashcode() method on this same object and it could be overridden to bypass the idHashcode.
  • [2] in contrast a custom hashcode() can change its value when object state changes.

anon classes^lambda: java perf

Based on [[JavaPerm]] P381

  • An anon class requires an actual *.class file created by javac compiler and loaded from serialized form (usually disk).
  • No such class file for a lambda.

More than half the interview questions are about fancy theoretical knowledge, so this is knowledge valuable to interviews.

This difference has very limited performance impact, as of java 8. This performance perspective is unimportant to interviews, IMHO.java

 

java local var( !! fields)need explicit initialization

http://stackoverflow.com/questions/268814/uninitialized-variables-and-members-in-java briefly mentions the reason.

Instance variables (i.e. fields) of object type default to being initialized to null. Local variables of object type are not initialized by default and it’s a compile time error to access an undefined variable.

For primitives, story is similar

java 8 default method – phrasebook

[[mastering lambdas]] is concise about method call resolution — corner cases, backward incompatibilities… I’m glad to be able to understand all of the practical issues.

j4, mtv — and the problem addressed : adding methods to a published interface. Impossible before java 8. Need to really understand it.

MI … isn’t a problem in java 8 – no “state” allowed in default methods.

vs abstract classes – instance state…

diamond – not a problem in itself

why delayed for so long – aversion of  MI

java method taking a single argument but 2 alternative types

Requirement: method read() in an interface IReader needs to accept a single argument but of various types

read(Book b) to be implemented by one concrete class BookReader
read(Score s) to be implemented by another concrete class ScoreReader

Suppose we want to unify the 2 read() methods into one unified method, so a “client” can get an instance of Reader and simply pass in either a book or a score. C# probably has language support for this, but in Java …

Solution 1: use Object argument

Solution 2: declare
read(T content, Class argumentClass);

BookReader.java implements
read(T content, Class argumentClass){
if (content instanceof Book){….
}

Paradoxically IDE may warn you that argumentClass is an unused variable inside the method. However Compiler use it to enforce type safety —

myReader.read(someBook, Integer.class);// won’t compile. Book.class required

address of a java object (and virtual/physical memory)

XR,

(another blog post) We once discussed how to find the address of a java object. The address has to be hidden from application programs since the garbage collector often need to relocate the object through the generational heap. Therefore any reference variable we use in java will let us read/write the “pointee” object but won't reveal address.

However, the address is visible to the garbage collector and some of the C code integrating with java via JNI or other means. It has to be visible because C uses pointers. A pointer holds a memory address. If a C function uses a pointer, then the C function can print out the address.

By the way, all along we are talking about virtual memory addresses, which could be anything from 0 to 0xFFFFFFFF ie 32-bit integer, even on a 128MB RAM laptop.

The virtual memory module in the kernel translates between virtual memory address and physical RAM address.

Q: Is it every possible for a C program to see the physical RAM address of an object? Here are my tentative answers so please correct me —

A: yes for the C program implementing the virtual memory module itself. This module runs in probably the lowest layer in the kernel. Virtual memory module probably gets loaded first so that a 32MB RAM laptop can load a 50M operation system. Virtual memory continues to be extremely relevant since no machine has enough RAM to fill up a 64 bit address space.

A: no for any other C program running on top of virtual memory module.

variable can’t live on the heap; only objects can

See also post [[a heap-stack dual variable]]

an object can live on the heap or the stack; but a variable can’t live on the heap. It’s either a stackVar or a field (or occasionally a global). That begs the questions

Q: what if a stack ref/ptr seated to a heap obj gets out of scope?
A: leak. unreachable object — need garbage collector.

Q: what if a field ptr/ref seated to a heap obj gets destructed with its host object?
A: the host dtor simply frees/reclaims the 4-byte memory, without calling delete() on the ptr. Item 7 [[eff c++]] says the “dtor” of a ptr is a no-op.
A: custom virtual dtor needed in the host object.

In java, a variable is either a field or a stackVar. An object is always on the heap

java always pass-by-value

A ref-type argument is passed by value — a copy of the remote-control, pointing to the same object

Once you point “critique_arg” to a new object, this method loses contact with the original critique object ] the caller method.

private boolean recordFault(Critique critique_arg, String brokenSlot){
String message = “Required slot ” + brokenSlot.toUpperCase() + ” missing.”;
critique_arg = new Critique(Critique.Severity.Critical, 0, slot, Critique.Type.ORDER);

By the way, the original object will get garbage collected if the variable in the caller method also gets assigned a new object.