Late cleanup of stack objects
Arnaud Masson
arnaud.masson at fr.ibm.com
Fri Nov 11 14:01:05 UTC 2022
Ron,
Indeed, it’s different with normal warmup as you suspected.
The threshold is between 500 and 600 loops (not fully reproducible).
After around 600 iterations, the bigBuffer is not retained, so it’s good.
Test code below.
So it mitigates my concern of retained objects in sync code vs retained in async code, but I think it’s still maybe not ideal since method compilation is related to CPU cost and not memory usage. (“capture” behavior on suspended stack call should be more predictable and unrelated to JIT, like for lambda.)
thanks
Arnaud
------
import java.lang.management.ManagementFactory;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main1b {
static int iter = 0;
static final ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
public static void main(String[] args) throws ExecutionException, InterruptedException {
var timer = new Timer();
var memBean = ManagementFactory.getMemoryMXBean();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.gc();
System.out.println("--- " + memBean.getHeapMemoryUsage());
}
}, 5_000, 5_000);
for (int i=0; i<600; i++) // ******* warmup ******
myApp(0, 0);
myApp(Long.MAX_VALUE, 1024 * 1024 * 1024);
}
private static void myApp(long durationMs, int buffSize) throws ExecutionException, InterruptedException {
var future = executor.submit(() -> {
try {
iter ++;
System.out.println("Starting work, iter #" + iter);
var bigBuffer = new byte[buffSize];
System.out.println("bigBuffer size: " + bigBuffer.length);
// bigBuffer = null;
slowIO(durationMs);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
future.get();
}
private static void slowIO(long durationMs) throws InterruptedException {
System.out.println("Starting slowIO");
Thread.sleep(durationMs);
}
}
>Can you test with C2 engaged normally through warmup?
>
>
>On 8 Nov 2022, at 13:56, Arnaud Masson <arnaud.masson at fr.ibm.com> wrote:
>
>
>> I will check if C2 helps, but afaik since it’s triggered when method is
>> used often (not because the method consumes significant memory), it’s
>> not ideal to count on it anyway. Moreover, I suspect it’s not documented
>> public behavior while lambda capture is well defined.
>
>
>I have checked the following example with (no debugger)
>
>--enable-preview
>-XX:-TieredCompilation
>-Xbatch
>-Xcomp
>-Xlog:nmethod+install
>
>… to force C2, but the bigBuffer is still retained.
>
>(Won’t C2 clear a stack ref only if it can be reused in the same scope for another java var?)
>
>Thanks
>Arnaud
Unless otherwise stated above:
Compagnie IBM France
Siège Social : 17, avenue de l'Europe, 92275 Bois-Colombes Cedex
RCS Nanterre 552 118 465
Forme Sociale : S.A.S.
Capital Social : 664 069 390,60 €
SIRET : 552 118 465 03644 - Code NAF 6203Z
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20221111/dfd501a9/attachment-0001.htm>
More information about the loom-dev
mailing list