Thursday, July 18, 2019

How memory works in Java?

As a developer, it is extremely important to understand how memory management in java works. It can help avoid creating difficult to trace problems.

This blog post would give a simplistic view of memory management in java.

With respect to memory management of Java applications, you need to understand two terms, the stack and the heap
The memory of a Java application is divided into two sections, the STACK and the HEAP.

STACK

In a single Java application, there can be one or more than one stack(s). That is, each thread in Java has its own stack.

Stack is a last in first out data structure. The JVM knows exactly when the data on the stack can be destroyed.
All local variables are created on the stack, and they are automatically popped from the stack on encountering the closing braces of the block that created the variable.

As each thread has its own stack, the data on the stack can only be seen by the thread that owns the stack.

HEAP

Heap allows us to store data that has a longer lifetime than a single code block.
In an application you have a single heap, that is shared across all threads.
In java all objects are stored on the heap.
For an object on the heap, the pointer reference to it will be stored on the stack.

Monday, July 15, 2019

Java Strings


String literals and String Objects


String s1 = "abc";
String s2 = "abc";

Both string s1 and s2 refer to the same string object and value residing in the string literal pool.


String A = new String("abc");
String B = new String("abc");


The two strings A & B are two different string objects, because we used the string constructor to create these two objects. These live in the heap.

Usually you would create string literals over string objects because it gives the compiler a chance to optimize your code.

Immutability of strings.


Strings are also immutable in java. For understanding immutability you can read my post here.

Since strings are immutable, we have classes like StringBuilder and StringBuffer to make string like objects that are immutable.
Both StringBuilder and StringBuffer provide methods like append(), insert(), delete(), substring(), toString() etc. for string manipulation.

You can look at the String APIs here.

StringBuilder vs. StringBuffer


StringBuffer is thread safe as its methods are synchronized whereas StringBuilder is not.


String equality


Given below are three strings.

String a = "hello";
String b = "hello";
String obj = new String("hello");

What would the following equality operators return?

a==obj; // false
a==b; // true
a.equals(obj); //true
a.equals(b); //true

P.S From Java9, strings are now stored as byte arrays instead of char arrays.

Tuesday, July 9, 2019

Java Static Initialization vs. Instance Initialization - When to use which?


Static Initialization

Typically static initialization block is used to initialize static variables of a class. The block is called at the time of class initialization. It is called only once. You can initialize static variables inline. If more complicated logic is required for initialization, a static initialization block can be used. The static initialization blocks are called in the order in which they occur, and they are called before the constructors.

For example:


The output of the above code is as shown below.


Instance Initialization

Instance Initialization or Initializer Block is called whenever an instance of the class is created.
It can be used to execute code that is common to all constructors. This block is executed before the constructor is executed.

For example:

The output of the above code is as shown below.


Ref: https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

Sunday, July 2, 2017

Do you ssh too often and to many different machines?

It's been a long time, since I last wrote a post. And this is going to be a short one.
At my recent job, we have all these test environments (about 3500 of them) that have the same username and password.
I kind of got tired typing the username and password every time I had to login to a machine to test out something.

Well a keyless access would definitely have made things easier, but you can understand why you couldn't have keyless access to 3500 environments, each running the risk of being phoenixed anytime.

I created a small expect script to get around the problem. Expect is a bash utility, that helps provide inputs in an automated way for scripts that expect user inputs. You may need to install it.

On a OsX machine, you can simply do brew install expect
#!/usr/bin/expect
set user ""
set ip [lindex $argv 0]
set password ""
spawn ssh $user@$ip
expect "password"
send "$password\r"
interact

The interact on last line opens an interactive ssh shell.

Now, you can save this with a .exp extension, give an executable permission to it. Setup an alias, so that your newssh command lands to this, and you are all set.
This has made me save a couple of seconds on every login. And now I am wondering why did I wait for so many months before doing this :)

Monday, December 5, 2016

10 Intellij Idea Must Know Shortcuts on Ubuntu

  1. Optimizing imports - Ctrl + Alt+ O
  2. Auto Imports - Alt+enter
  3. System.out.println - type sysout, then press tab
  4. Open a file - Ctrl+N
  5. GoTo Function in class - Ctrl + F12
  6. Auto Indent - Ctrl + Alt + I
  7. Basic Code Completion - Ctrl + Space
  8. Comment a line of code - Ctrl + /
    Uncomment a line of code - Ctrl + Shift + /
  9. Duplicate the current line - Ctrl + D
  10. Finally, Find any action by name - Ctrl + A

Monday, October 24, 2016

Mount a Remote system as a drive on OSx using SSH

Recently I ran into a situation where I needed to mount a remote system folder on my OSx for ease of sharing and convenience. You can totally do without this by just using the terminal. However, writing this hoping to help those who need to do this for one or the other reason.

1. Install Fuse and SSHFS

Download FUSE and SSHFS from OSx Fuse site. Follow the instructions to install Fuse, followed by SSHFS.

2. Create a folder on your mac. This will be the mount point of the remote folder.

anjanas:~ $ ls
Applications Library  Public  id_rsa
Desktop  Movies  PycharmProjects test.txt
Documents Music  dev-vm-mount workspace
Downloads Pictures dwhelper
anjanas:~ $ mkdir mount
anjanasblrmbp:~ $ ls
Applications Library  Public  id_rsa
Desktop  Movies  PycharmProjects mount
Documents Music  dev-vm-mount test.txt
Downloads Pictures dwhelper workspace

3. Create a keyless access to your server

Refer this link for the same.

4. Mount the remote system as a folder on OSx

sshfs -o IdentityFile=~/.ssh/id_rsa anjana@remote.ip:/home/anjana/workspace ~/mount

Now you can treat the remote folder as any other folder on your machine.

Unmounting this system can be achieved as follows:
sudo diskutil umount force ~/mount

That's it for this post.
References: Mount a remote system as a drive on Mac OSx

Thursday, March 31, 2016

Accessing Solr Cloud on AWS from SolrJ

We have a Solr cloud installation on AWS EC2 instances. We use the SolrJ Client from our Java application. Till date we used to have a Solr Cloud installation on our local machine in order to test the code against. As the team started growing, we realized that we should have a way to access the AWS Solr Cloud from our local boxes, so that the Solr Cloud setup on local is not a blocker for feature development.

When I started looking around the web for a solution to this issue, I had to mix a few things from a few different documentation pages and this stackoverflow page. Decided to write this blog post to help out others who are running into the same issue. I hope it helps.

So first let's try to understand the reason behind why you get the java.net.UnknownHostException from the SolrJ client.
When the solr cloud is run, each instance registers itself with the zookeeper that is running. This is done with the private IP of the solr machine. So when SolrJ connects to zookeeper, it gets the private IP. And then SolrJ tries to hit the Solr instance with the private IP, leading to an unknown host exception.

In order to get around this you can follow these steps:
Step 1: Run the solr instance with a host name. Zookeeper will use this hostname.
./bin/solr start -cloud -h hostname -p 8985 -z localhost:2181

Step 2: Add the host entry to the /etc/hosts file on your local machine corresponding to the public ip of the solr machine.

And you are done. You can run the java application that uses SolrJ client on your local machine and access the Solr Cloud running on your AWS instance :)