Details
Description
ADDITIONAL SYSTEM INFORMATION :
Linux mint 19.3, glibc 2.27, jdk 11u2 and 11u4 and 13u2.
A DESCRIPTION OF THE PROBLEM :
Following program:
class Hello {
private static int doIt(int i) throws InterruptedException {
if (i == 4000) {
synchronized (Hello.class) {
System.out.println("Waiting");
Hello.class.wait();
System.out.println("Waking up");
}
return i;
}
return i + doIt(i + 1);
}
public static void main(String[] args) throws Exception {
for (int t = 0; t < 1; t++) {
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 300; i++) {
threads.add(new Thread(() -> {
try {
doIt(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}));
}
for (Thread thread : threads) {
thread.start();
}
System.in.read();
synchronized (Hello.class) {
Hello.class.notifyAll();
}
for (Thread thread : threads) {
thread.join();
}
threads.clear();
System.out.println("GC");
System.gc();
System.in.read();
}
}
}
Run on defualts on JDK 11 and 13, before first "System.in.read();" RSS is around 50MB, after you hit enter, and goes to next "System.in.read();" RSS become over 5GB. NMT report:
Total: reserved=5609554KB, committed=94558KB
- Java Heap (reserved=4071424KB, committed=20480KB)
(mmap: reserved=4071424KB, committed=20480KB)
- Class (reserved=1056936KB, committed=7848KB)
(classes #1046)
( instance classes #936, array classes #110)
(malloc=168KB #1417)
(mmap: reserved=1056768KB, committed=7680KB)
( Metadata: )
( reserved=8192KB, committed=6912KB)
( used=6835KB)
( free=77KB)
( waste=0KB =0,00%)
( Class space:)
( reserved=1048576KB, committed=768KB)
( used=656KB)
( free=112KB)
( waste=0KB =0,00%)
- Thread (reserved=4220063KB, committed=4195543KB)
(thread #25)
(stack: reserved=25644KB, committed=1124KB)
(malloc=85KB #141)
(arena=4194334KB #49)
- Code (reserved=247763KB, committed=7623KB)
(malloc=75KB #741)
(mmap: reserved=247688KB, committed=7548KB)
- GC (reserved=202727KB, committed=52423KB)
(malloc=17843KB #2231)
(mmap: reserved=184884KB, committed=34580KB)
- Compiler (reserved=135KB, committed=135KB)
(malloc=4KB #58)
(arena=131KB #5)
- Internal (reserved=1369KB, committed=1369KB)
(malloc=1329KB #3398)
(mmap: reserved=40KB, committed=40KB)
- Other (reserved=2KB, committed=2KB)
(malloc=2KB #1)
- Symbol (reserved=2706KB, committed=2706KB)
(malloc=1547KB #6252)
(arena=1159KB #1)
- Native Memory Tracking (reserved=475KB, committed=475KB)
(malloc=184KB #2605)
(tracking overhead=291KB)
- Arena Chunk (reserved=18014398505287857KB, committed=18014398505287857KB)
(malloc=18014398505287857KB)
- Logging (reserved=4KB, committed=4KB)
(malloc=4KB #186)
- Arguments (reserved=18KB, committed=18KB)
(malloc=18KB #479)
- Module (reserved=58KB, committed=58KB)
(malloc=58KB #1025)
Async-profiler and jemalloc profiling graph shows, that allocation is done in:
- VM_BulkRevokeBias::doit
- bulk_revoke_or_rebias_at_safepoint
- get_or_compute_monitor_info
Your source code:
GrowableArray<MonitorInfo*>* info = thread->cached_monitor_info();
if (info != NULL) {
return info;
}
info = new GrowableArray<MonitorInfo*>();
Can be an issue with standard malloc in glibc, Setting malloc_arena_max=1 changes nothing, nut switching to jemalloc partially solves the problem (ther is RSS spike, but memory is release later)
With disablied biased locking (-XX:-UseBiasedLocking) RSS is normal, no huge consuption.
---------- BEGIN SOURCE ----------
import java.util.ArrayList;
import java.util.List;
class Hello {
private static int doIt(int i) throws InterruptedException {
if (i == 4000) {
synchronized (Hello.class) {
System.out.println("Waiting");
Hello.class.wait();
System.out.println("Waking up");
}
return i;
}
return i + doIt(i + 1);
}
public static void main(String[] args) throws Exception {
for (int t = 0; t < 1; t++) {
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 300; i++) {
threads.add(new Thread(() -> {
try {
doIt(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}));
}
for (Thread thread : threads) {
thread.start();
}
System.in.read();
synchronized (Hello.class) {
Hello.class.notifyAll();
}
for (Thread thread : threads) {
thread.join();
}
threads.clear();
System.out.println("GC");
System.gc();
System.in.read();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
-XX:-UseBiasedLocking
FREQUENCY : always
Linux mint 19.3, glibc 2.27, jdk 11u2 and 11u4 and 13u2.
A DESCRIPTION OF THE PROBLEM :
Following program:
class Hello {
private static int doIt(int i) throws InterruptedException {
if (i == 4000) {
synchronized (Hello.class) {
System.out.println("Waiting");
Hello.class.wait();
System.out.println("Waking up");
}
return i;
}
return i + doIt(i + 1);
}
public static void main(String[] args) throws Exception {
for (int t = 0; t < 1; t++) {
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 300; i++) {
threads.add(new Thread(() -> {
try {
doIt(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}));
}
for (Thread thread : threads) {
thread.start();
}
System.in.read();
synchronized (Hello.class) {
Hello.class.notifyAll();
}
for (Thread thread : threads) {
thread.join();
}
threads.clear();
System.out.println("GC");
System.gc();
System.in.read();
}
}
}
Run on defualts on JDK 11 and 13, before first "System.in.read();" RSS is around 50MB, after you hit enter, and goes to next "System.in.read();" RSS become over 5GB. NMT report:
Total: reserved=5609554KB, committed=94558KB
- Java Heap (reserved=4071424KB, committed=20480KB)
(mmap: reserved=4071424KB, committed=20480KB)
- Class (reserved=1056936KB, committed=7848KB)
(classes #1046)
( instance classes #936, array classes #110)
(malloc=168KB #1417)
(mmap: reserved=1056768KB, committed=7680KB)
( Metadata: )
( reserved=8192KB, committed=6912KB)
( used=6835KB)
( free=77KB)
( waste=0KB =0,00%)
( Class space:)
( reserved=1048576KB, committed=768KB)
( used=656KB)
( free=112KB)
( waste=0KB =0,00%)
- Thread (reserved=4220063KB, committed=4195543KB)
(thread #25)
(stack: reserved=25644KB, committed=1124KB)
(malloc=85KB #141)
(arena=4194334KB #49)
- Code (reserved=247763KB, committed=7623KB)
(malloc=75KB #741)
(mmap: reserved=247688KB, committed=7548KB)
- GC (reserved=202727KB, committed=52423KB)
(malloc=17843KB #2231)
(mmap: reserved=184884KB, committed=34580KB)
- Compiler (reserved=135KB, committed=135KB)
(malloc=4KB #58)
(arena=131KB #5)
- Internal (reserved=1369KB, committed=1369KB)
(malloc=1329KB #3398)
(mmap: reserved=40KB, committed=40KB)
- Other (reserved=2KB, committed=2KB)
(malloc=2KB #1)
- Symbol (reserved=2706KB, committed=2706KB)
(malloc=1547KB #6252)
(arena=1159KB #1)
- Native Memory Tracking (reserved=475KB, committed=475KB)
(malloc=184KB #2605)
(tracking overhead=291KB)
- Arena Chunk (reserved=18014398505287857KB, committed=18014398505287857KB)
(malloc=18014398505287857KB)
- Logging (reserved=4KB, committed=4KB)
(malloc=4KB #186)
- Arguments (reserved=18KB, committed=18KB)
(malloc=18KB #479)
- Module (reserved=58KB, committed=58KB)
(malloc=58KB #1025)
Async-profiler and jemalloc profiling graph shows, that allocation is done in:
- VM_BulkRevokeBias::doit
- bulk_revoke_or_rebias_at_safepoint
- get_or_compute_monitor_info
Your source code:
GrowableArray<MonitorInfo*>* info = thread->cached_monitor_info();
if (info != NULL) {
return info;
}
info = new GrowableArray<MonitorInfo*>();
Can be an issue with standard malloc in glibc, Setting malloc_arena_max=1 changes nothing, nut switching to jemalloc partially solves the problem (ther is RSS spike, but memory is release later)
With disablied biased locking (-XX:-UseBiasedLocking) RSS is normal, no huge consuption.
---------- BEGIN SOURCE ----------
import java.util.ArrayList;
import java.util.List;
class Hello {
private static int doIt(int i) throws InterruptedException {
if (i == 4000) {
synchronized (Hello.class) {
System.out.println("Waiting");
Hello.class.wait();
System.out.println("Waking up");
}
return i;
}
return i + doIt(i + 1);
}
public static void main(String[] args) throws Exception {
for (int t = 0; t < 1; t++) {
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 300; i++) {
threads.add(new Thread(() -> {
try {
doIt(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}));
}
for (Thread thread : threads) {
thread.start();
}
System.in.read();
synchronized (Hello.class) {
Hello.class.notifyAll();
}
for (Thread thread : threads) {
thread.join();
}
threads.clear();
System.out.println("GC");
System.gc();
System.in.read();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
-XX:-UseBiasedLocking
FREQUENCY : always