Friday, September 16, 2016

String StringBuffer StringBuilder

  1. String is Java class backed by char array
  2. String in immutable (you can’t change the object itself but can change the reference of the object) since String objects are cache in String pool. String used to open JDBC and for opening file, so security can become a thread if class in not immutable
  3. String is final so no one can override the class
  4. String overrides equals() and hashCode() methods, two Strings are equal only if they have same characters in same order. Note that equals() method is case sensitive, so if you are not looking for case sensitive checks, you should use equalsIgnoreCase() method.
  5. We can create string in 2 ways
·         By using new : A new object is created
String B2= “Hi”; --O1
String A1=new String(“Hi”); -- O2
·         By using String literal “”- checks for similar String literal and if found same reference
String A2= “Hi”; -- Obj1
String B2= “Hi”; same object
String A1=new String(“Hi”); -- Obj2
String B1=new String(“Hi”); -- Obj2

  1. Immutable: When we modify a string a new object is created along with the existing one and the reference to the modified is changed. A,BàObj1 ..after modification Aà Obj1 Bà Obj2
String A="Hi";
            String B ="Hi";
            if(A.equals(B)){ -- True
                  System.out.println("A=B");
            }
B=B.toUpperCase();
                  if(A.equals(B)){ -- False
                        System.out.println("2 A=B");
                  }else{
                        System.out.println("2 A!=B");}
  1. Since immutable it is thread-safe
  2. Allows hashcode to be stored in cache so it is fast
  3. String maintained in String pool more specifically in PermGen Space
  4. .equals and == à == refers to references
String personalLoan = new String("loans");
      String homeLoan = new String("loans");
                 
      //since two strings are different object result should be false
            boolean result = personalLoan == homeLoan; -- False
           //since strings contains same conten , equals() should return true
      result = personalLoan.equals(homeLoan);
                 
homeLoan = personalLoan;
//since both homeLoan and personalLoand reference variable are pointing to same object
      //"==" should return true
      result = (personalLoan == homeLoan);
  1. Important methods indexOf(); lastIndexOf(); matches(String regex)
  2. Substring method: can create memory leaks. Backed by array of char. if beginIndex is equal to length in substring or beginindex = endindex null string will be returned.
    How substring works: it internally calls String (int offset, int count, char value [])
    constructor to create new String object. In this char value[] is the original string. So if the original string is very long the new string will be equally long. Also, this will stop original string from being garbage collected, in case it does not have live references. Thus creating memory leaks where memory is retained even though it is not required.
Solution: Simple solution is to trim the string, and keep size of character array according to length of substring. Or to use intern() method on substring since it is an original string it will occupy only the required space. Intern() has to be called on substring and not original string
String str="hello hi how are you";
            String subStr=new String(str.substring(0,3));
Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string.

subStr.intern();
  1. + can be used to concat strings. Internally it uses StringBuffer or StringBuilder which are mutable thus are temporary.
  2. trim(): trims the leading and trailing spaces in a string. If removes white spaces then a new string is returned else same string is returned. Inside trim(), if no trailing and leading whitespaces then this else substring method is called which in turn returns a new string.
String str1=new String(" hello hi how are you");
      String str2=new String("hello");
      String trim1=str1.trim();
String trim2=str2.trim();
      if(trim1.equals(str1)){
            System.out.println("true");
            }else{
            System.out.println("false"); --False
            }
      if(trim2.equals(str2)){
            System.out.println("true"); --True
            }else{
            System.out.println("false");
  1. split() can be used to split a string based on delimiter.
String str1=new String(" hello hi how are you");
String[] splitString=str1.split(" ");
String[] splitString=str.split(“\\|”);
  1. don’t store sensitive information in String since String is immutable and is stored in string pool(memory), it stays on heap for a long time and exposes risk of being seen by anyone who has access to Java memory like reading from dump. Instead char[] should be used to store password or sensitive information.
  2. Encoding is important in java specially if u use languages like German or French.  String represents a string in the UTF-16 format.

String Builder and String Buffer
1.      If string is created with String literal, it remains in String Pool. Since String is immutable, it remains in string pool and any method on string creates new String.

2.      StringBuffer is mutable i.e. you can modify a string buffer without creating a new object.


3.      String Builder is copy of String Buffer except, String Buffer methods are synchronized and hence is thread-safe which make is slow at the same time.

4.      Use String if you require immutability, use StringBuffer in java if you need mutable + thread-safety and use StringBuilder in Java if you require mutable + without thread-safety.

Thursday, September 15, 2016

Memory - Heap v/s Stack

  1. Heap Space
·         Part of memory allocated to JVM by OS
·         used by java runtime to allocate memory to Objects and JRE classes
·         Whenever we create any object, it’s always created in the Heap space
·          Garbage Collection runs on the heap memory to free the memory used by objects that doesn’t have any reference. 
·         Any object created in the heap space has global access and can be referenced from anywhere of the application
·         java.lang.OutOfMemoryError: Java Heap Space when full. Before throwing this error garbage collector is run and if even then no space is available the error is thrown
·         heap size can be increased by using JVM options -Xms and -Xmx. Xms denotes starting size of Heap while -Xmx denotes maximum size of Heap in Java
·         you can’t change the size of Heap in Java dynamically, you can only provide Java Heap Size parameter while starting JVM
·         use either JConsole or Runtime.maxMemory(), Runtime.totalMemory(), Runtime.freeMemory() to query about Heap size programmatic in Java



  1. Java Memory Stack
·         used for execution of a thread
·         contain method specific values that are short-lived and references to other objects in the heap that are getting referred from the method. 
·         referenced in LIFO
·         Whenever a method is invoked, a new block is created in the stack memory for the method to hold local primitive values and reference to other objects in the method. As soon as method ends, the block becomes unused and become available for next method.
·         java.lang.StackOverFlowError when full
·         very less in size as compared to Heap Size

Garbage Collection and Java Heap

1.      New Generation of Java Heap is part of Java Heap memory where newly created object are stored
2.      During the course of application many objects created and died but those remain live they got moved to Old or Tenured Generation by Java Garbage collector thread
3.      Perm space of Java Heap is where JVM stores Meta data about classes and methods, String pool and Class level details
4.      Mechanism to reclaim heap space and is carried by a daemon thread called garbage collector
5.      We can’t trigger garbage collection. It is triggered by JVM whenever it feels the heap size has increased too much.
6.      System.gc() and Runtime.gc() are sent to JVM but does not guarantee they work
7.      Before removing an object finalize() method of that object and gives an opportunity to do any cleanup
8.      An object is available for garbage collection if it is not reachable by any live threads or references are null.
9.      Cyclic dependencies are not counted as the reference so if object A has a reference to object B and object B has a reference to Object A and they don't have any other live reference then both Objects A and B will be eligible for Garbage collection.


Thread

  1. Thread can be implemented either extending Thread Class or implementing Runnable Interface. Since we can’t extend 2 classes in Java implementing Runnable is better option
  2. States of Thread
·         New: The thread is created
·         Runnable: thread is runnable only after start() method
·         Running: thread is executing after run() method
·         Waiting/Blocked: thread is waiting for other thread to finish job. Once wait is over, it’s state is changed to runnable and it’s moved back to runnable thread pool
·         Dead: once thread finished executing, it’s state is changed to dead and it is not considered alive
·         start() and run(): start() internally calls the run() method. While we use start() method a new thread is created when run() is called internally to start(). But when we call run() method separately, it is executed in same thread.
  1. Object class has 3 final methods that allow thread to communicate about lock status of thread
·         wait(): has 3 variances. In one it waits indefinitely and call notify() notifyAll() method to wake up current thread. In other two the thread wait for a definite amout
·         notify(): wakes up only 1 thread waiting on an object and then that thread execution starts. If multiple threads are waiting on an object the method wakes up only 1 thread. Which thread will wake up is decided by OS implementation of thread management.
·         notifyAll(): wakes up all the threads waiting on the object. But which thread will execute first will depend on OS implementation. It is usually implemented in producer consumer problems.
·         join(): used to pause the current thread execution until unless specified thread is dead
thread1.join(); thread2.start() à thread two will start only after thread 1 is dead
thread1.join(2000); thread2.start() àthread two will start only after 2 sec or thread 1 is dead
  1. Message: A java class on which thread will work and call the wait() notify() methods
  2. Waiter: A class which will wait for other threads to invoke notify methods to complete its processing. Waiter thread is owning monitor on Message object using synchronized block
  3. Runnable and Callable: runnable from JDK1.0 while callable is from JDK 1.5. Callable’s call() can return value and throw exception which is not possible in Runnable’s run(). Callable return future object, which can hold result of a computation.
  4. For multithreaded environment thread safety a concern since updating an element is 3 steps process, taking the variable editing it and writing back. Threadsafety can be assured either by
·         Synchronization
·         Using atomic interger instead of ++
AtomicInteger atomicCount = new AtomicInteger( 0 );


  1. Thread safe by default in Java
·         Immutable objects like String
·         Read-only or final variables
·         Static variables if not initialized properly become major cause of thread-safety issues
·         Thread-safe classes like: Vector; Hashtable; ConcurrentHashMap; String
·         Atomic operation are thread-safe
·         Local variables are thread-safe
·         Volatile keyword for variables
  1. Also JVM plays a spoiler since it can reorder code for optimization, so the code which looks sequential and runs fine in development environment not guaranteed to run similarly in production environment because JVM may ergonomically adjust itself as server JVM and perform more optimization and reorder which cause thread-safety issues.

  1. When we create a Thread in java, by default it’s a user thread and if it’s running JVM will not terminate the program. When a thread is marked as daemon thread, JVM doesn’t wait it to finish and as soon as all the user threads are finished, it terminates the program as well as all the associated daemon threads.
        Thread dt = new Thread(new DaemonThread(), "dt");dt.setDaemon(true);

  1. Deadlock: when multiple threads are waiting for each other to release the resource thus causing cyclic dependency

  1. We can share data between two threads by using shared objects or concurrent data structures like Blocking queue. For ex. Consumer producer pattern. JavaBlocking Queue is a java Queue that support operations that wait for the queue to become non-empty when retrieving and removing an element, and wait for space to become available in the queue when adding an element.

  1. Java thread pool manages the pool of worker threads, it contains a queue that keeps tasks waiting to get executed. We can use ThreadPoolExecutor to create thread pool in java.

Wednesday, September 14, 2016

Synchronization

      1. Important in case of multi-threaded environment
      2. Synchronization can be of Java Object or Java Class
      3. Synchronized and volatile keywords are used for synchronizing i.e. mutual exclusive access
      4. Concurrent access of shared objects introduces errors like thread interference and memory consistency. To avoid these errors object must be synchronized
      5. If shared object is read-only or immutable like ‘String’ then synchronization not required despite running multiple threads
      6. JVM guarantees java synchronized code is executed one at a time
      7. synchronized keyword is related to locking and unlocking. When entering the synchronized block or method it needs to acquire lock so it reads from main memory rather than cache memory. When exiting the synchronized block or method it needs to release the lock so it flushes write operation in main memory. This eliminates memory consistency errors.
      8. Any code with synchronized method or synchronized block is mutually exclusive
      9. static synchronized method and non-static synchronized method. In Static synchronized method class object is locked (class level lock) where as in non-static synchronized current object (this) is locked (object level lock). If we have a non-static and static method on same object/ scenario, they can run in parallel since one will run on class object and other on this object.
      public class Counter{ 
      private static int count = 0; 
      public static synchronized int getCount(){ return count;}
                  public synchoronized setCount(int count){ this.count = count; } }

      1. can’t have synchronized variable it gives compilation error. So we can have volatile variable since this reads variable from main memory rather than cache
      2. block synchronization preferred over method since only the required part is made mutually exclusive since it comes at the cost of performance
      3. if object used inside synchronized block is null then nullpointer exception is thrown
      4. java synchronized keyword is re-entrant in nature
      5. does not allow concurrent read. By using concept of lock stripping and using different locks for read and write we can overcome this limitation.
      6. synchronized keyword is used to limited access in only 1 JVM. If there are different JVM or different file bases or DB, synchronized keyword does not work and we need to implement global locks.
      7. Can result in dead-lock or starvation in multi threading is synchronization not properly implemented.
      8. Constructor can’t be synchronized
      9.  Important methods related to synchronization: wait(), notify(), notifyAll() which is defined in ObjectClass
      10. Don’t synchronize non-final fields in synchronized block since the value can change at any time and then different threads may be synchronizing different objects
      11. String is not recommended as a lock in java synchronized block because a string is an immutable object and literal string and interned string gets stored in String pool. so by any chance if any other part of the code or any third party library used same String as there lock then they both will be locked on the same object despite being completely unrelated which could result in unexpected behavior and bad performance. Instead of String object its advised to use new Object() for Synchronization in Java on synchronized block.
      private static final String LOCK = "lock";   //not recommended
         private static final Object OBJ_LOCK = new Object(); //better
         public void process() {
                                        synchronized(LOCK) {
                                                       .......
            }
         }
      1. Calendar and SimpleDateFormat classes are not thread-safe and require external synchronization in multi-threaded environment
      2.  
                     private static final String LOCK = "lock";   //not recommended
                     private static final Object OBJ_LOCK = new Object(); //better
                     public void process() {
                                     synchronized(LOCK) {
                                                    .......
                        }
                     }