Сравнение GC (Serial, Parallel, G1)
Тестировал разные GC при работе со следующим тестовым классом:
public class User {
private String name;
private String password;
private int age;
public User(String name, int age, String password) {
this.name = name;
this.age = age;
this.password = password;
}
@Override
protected void finalize() throws Throwable {
System.out.println("Removed " + age + " " + name);
}
public static void main(String[] args) throws OutOfMemoryError, InterruptedException {
List<User> userList = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
userList.add(new User("name" + i, i, "pass"));
System.out.println(userList.get(i).toString());
}
}
@Override
public String toString() {
return "User{"
+ "name='" + name + '\''
+ ", password='" + password + '\''
+ ", age=" + age
+ '}';
}
}
при работе заметил, что Serial работает быстрее, чем Parallel, на основании следующей информации от GC. Результат работы Serial:
User{name='name8648', password='pass', age=8648}
[0.450s][info ][gc,start ] GC(36) Pause Full (Allocation Failure)
[0.451s][info ][gc,phases,start] GC(36) Phase 1: Mark live objects
[0.454s][info ][gc,phases ] GC(36) Phase 1: Mark live objects 3.514ms
[0.454s][info ][gc,phases,start] GC(36) Phase 2: Compute new object addresses
[0.455s][info ][gc,phases ] GC(36) Phase 2: Compute new object addresses 0.686ms
[0.455s][info ][gc,phases,start] GC(36) Phase 3: Adjust pointers
[0.456s][info ][gc,phases ] GC(36) Phase 3: Adjust pointers 1.375ms
[0.456s][info ][gc,phases,start] GC(36) Phase 4: Move objects
[0.456s][info ][gc,phases ] GC(36) Phase 4: Move objects 0.015ms
[0.456s][info ][gc,heap ] GC(36) DefNew: 575K(576K)->575K(576K) Eden: 511K(512K)->511K(512K) From: 63K(64K)->63K(64K)
[0.456s][info ][gc,heap ] GC(36) Tenured: 1407K(1408K)->1407K(1408K)
[0.456s][info ][gc,metaspace ] GC(36) Metaspace: 963K(4864K)->963K(4864K) NonClass: 874K(4352K)->874K(4352K) Class: 89K(512K)->89K(512K)
[0.456s][info ][gc ] GC(36) Pause Full (Allocation Failure) 1M->1M(1M) 5.950ms
[0.456s][info ][gc,cpu ] GC(36) User=0.00s Sys=0.00s Real=0.01s....
Результат работы Parallel
User{name='name3867', password='pass', age=3867}
[2.637s][info ][gc,start ] GC(335) Pause Full (Ergonomics)
[2.637s][info ][gc,phases,start] GC(335) Marking Phase
[2.639s][info ][gc,phases ] GC(335) Marking Phase 2.628ms
[2.639s][info ][gc,phases,start] GC(335) Summary Phase
[2.639s][info ][gc,phases ] GC(335) Summary Phase 0.011ms
[2.639s][info ][gc,phases,start] GC(335) Adjust Roots
[2.640s][info ][gc,phases ] GC(335) Adjust Roots 0.871ms
[2.640s][info ][gc,phases,start] GC(335) Compaction Phase
[2.645s][info ][gc,phases ] GC(335) Compaction Phase 5.133ms
[2.645s][info ][gc,phases,start] GC(335) Post Compact
[2.646s][info ][gc,phases ] GC(335) Post Compact 0.098ms
[2.646s][info ][gc,heap ] GC(335) PSYoungGen: 994K(1024K)->994K(1024K) Eden: 512K(512K)->512K(512K) From: 482K(512K)->482K(512K)
[2.646s][info ][gc,heap ] GC(335) ParOldGen: 511K(512K)->509K(512K)
[2.646s][info ][gc,metaspace ] GC(335) Metaspace: 1003K(4864K)->1003K(4864K) NonClass: 910K(4352K)->910K(4352K) Class: 92K(512K)->92K(512K)
[2.646s][info ][gc ] GC(335) Pause Full (Ergonomics) 1M->1M(1M) 9.005ms
[2.646s][info ][gc,cpu ] GC(335) User=0.00s Sys=0.00s Real=0.01s
[2.647s][info ][gc,heap,exit ] Heap
[2.647s][info ][gc,heap,exit ] PSYoungGen total 1024K, used 994K [0x00000000ffe80000, 0x0000000100000000, 0x0000000100000000)
[2.647s][info ][gc,heap,exit ] eden space 512K, 100% used [0x00000000ffe80000,0x00000000fff00000,0x00000000fff00000)
[2.647s][info ][gc,heap,exit ] from space 512K, 94% used [0x00000000fff00000,0x00000000fff78888,0x00000000fff80000)
[2.647s][info ][gc,heap,exit ] to space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
[2.647s][info ][gc,heap,exit ] ParOldGen total 512K, used 511K [0x00000000ffe00000, 0x00000000ffe80000, 0x00000000ffe80000)
[2.647s][info ][gc,heap,exit ] object space 512K, 99% used [0x00000000ffe00000,0x00000000ffe7ff00,0x00000000ffe80000)
[2.647s][info ][gc,heap,exit ] Metaspace used 1009K, capacity 4541K, committed 4864K, reserved 1056768K
[2.647s][info ][gc,heap,exit ] class space used 93K, capacity 404K, committed 512K, reserved 1048576K
Вопрос в следующем:
- почему Serial создаёт заметно больше объектов (размер кучи одинаков) и при этом показывает более быстрый результат. Paralell же работает в несколько потоков, значит должен работать быстрее (судя по шкале времени достижения последнего создаваемого объекта)?
- почему Serial заметно больше создает объектов? Или это так влияет разница в размерах регионов младшего поколения?