I have this program:
public static void main(String[] args) {
int sum = 0;
LinkedList<Integer> ll = new LinkedList<>();
for(int i=0;i<Long.MAX_VALUE;i++) {
sum += i;
if (sum % 3 == 0){
ll.add(i);
if (ll.size() % 1000 == 0)
System.out.println("Linked List size: " + ll.size());
}
}
}`
What I expected to see was integer object being created in the young generation, some of them added to the linked list moved to the old generation. So I expected young generation GC to happen consistently with objects being moved to the survivor spaces and then from there to the old generation. But what I find is that it is the old generation GC that is happening all the time and young generation GC is not happening at all. Is this some kind of optimization that the JVM is doing? Where the objects are being created in the old generation directly? As you can see in the below image young gc has happened only twice while old gc 41 times. Old Generation GC only
Next I tried the same code except that instead of adding the integer object to a linked list I just created a new Object() and to my surprise there were no young or old gc.
public static void main(String[] args) {
int sum = 0;
LinkedList<Integer> ll = new LinkedList<>();
for(int i=0;i<Long.MAX_VALUE;i++) {
sum += i;
Object obj = new Object();
}
}
Then I created random string objects:
public static void main(String[] args) {
int sum = 0;
LinkedList<Integer> ll = new LinkedList<>();
for(int i=0;i<Long.MAX_VALUE;i++) {
sum += i;
String s = String.valueOf(Math.random());
}
}
Now I see the famililar see-saw pattern with the objects being transferred to survivor spaces:
5.833: [GC (Allocation Failure) [PSYoungGen: 1048576K->1984K(1223168K)] 1048576K->2000K(4019712K), 0.0035789 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 12.678: [GC (Allocation Failure) [PSYoungGen: 1050560K->2000K(1223168K)] 1050576K->2024K(4019712K), 0.0023286 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 18.736: [GC (Allocation Failure) [PSYoungGen: 1050576K->1968K(1223168K)] 1050600K->2000K(4019712K), 0.0016530 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 24.346: [GC (Allocation Failure) [PSYoungGen: 1050544K->2000K(1223168K)] 1050576K->2040K(4019712K), 0.0016131 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 31.257: [GC (Allocation Failure) [PSYoungGen: 1050576K->1952K(1223168K)] 1050616K->2000K(4019712K), 0.0018461 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 38.519: [GC (Allocation Failure) [PSYoungGen: 1050528K->1984K(1395712K)] 1050576K->2040K(4192256K), 0.0022490 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 47.998: [GC (Allocation Failure) [PSYoungGen: 1395648K->256K(1394176K)] 1395704K->2153K(4190720K), 0.0024607 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
So my question is the GC smart enough to see that the objects created are not used anywhere and discard them? Why not with Strings?