Ich versuche zu verstehen, wie Java mit der Speicherzuweisung für Lambdas umgeht und ob es möglich ist, sie in einem GC-freien Stil für latenzkritische Anwendungen zu verwenden. Mein Ziel ist es herauszufinden, ob Lambdas verwendet werden können, ohne Müll zu erzeugen, da die Vermeidung von GC für meinen Anwendungsfall von entscheidender Bedeutung ist.
Im Folgenden finden Sie zwei Beispiele zur Veranschaulichung meiner Fragen. In beiden Lambda-Erfassungen wird effektiv die endgültige Variable erfasst.
Umgebung: Amazon Corretto 17.0.12 JDK, G1GC.
Beispiel 1 : Inline-Lambda
package com.example;
import java.util.List;
import java.util.function.Predicate;
public class LambdaTest {
private static final Something something = new Something();
public static void main(String[] args) {
String a = "hello there";
while (true) {
something.method(x -> x.equals(a));
}
}
}
class Something {
private final List list = List.of("1", "2");
void method(Predicate predicate) {
for (int i = 0; i < list.size(); i++) {
predicate.test(list.get(i));
}
}
}
Wenn dieser Code etwa 15 Sekunden lang ausgeführt wird, werden ~22 MB Speicher zugewiesen (wie mit Java Flight Recorder beobachtet). Dies ist überraschend für einen scheinbar einfachen Lambda-Aufruf.
Die GC-Protokolle zeigen auch viele „Cleanup“-Ereignisse und G1-Sammlungen. Warum passiert das?
public static void main(String[] args) {
String a = "hello there";
Predicate stringPredicate = x -> x.equals(a);
while (true) {
something.method(stringPredicate);
}
}
In diesem Beispiel wird das Lambda zuvor einer Variablen zugewiesen und in der Schleife wiederverwendet. Interessanterweise wird viel weniger Speicher zugewiesen (laut IDEA-Profiler-Hinweisen), aber fast die gleiche Anzahl an Safepoint-„Cleanup“-Ereignissen.
[img]https://i.sstatic. net/K5Ii7JGy.png[/img]
Ich versuche zu verstehen, wie Java mit der [b]Speicherzuweisung für Lambdas[/b] umgeht und ob es möglich ist, sie in einem [b]GC-freien Stil[/b] für latenzkritische Anwendungen zu verwenden. Mein Ziel ist es herauszufinden, ob Lambdas verwendet werden können, ohne Müll zu erzeugen, da die Vermeidung von GC für meinen Anwendungsfall von entscheidender Bedeutung ist. Im Folgenden finden Sie zwei Beispiele zur Veranschaulichung meiner Fragen. In beiden Lambda-Erfassungen wird effektiv die endgültige Variable erfasst. Umgebung: Amazon Corretto 17.0.12 JDK, G1GC. Beispiel 1 : Inline-Lambda [code]package com.example;
public class LambdaTest { private static final Something something = new Something();
public static void main(String[] args) { String a = "hello there"; while (true) { something.method(x -> x.equals(a)); } } }
class Something { private final List list = List.of("1", "2");
void method(Predicate predicate) { for (int i = 0; i < list.size(); i++) { predicate.test(list.get(i)); } } } [/code] Wenn dieser Code etwa 15 Sekunden lang ausgeführt wird, werden [b]~22 MB Speicher zugewiesen[/b] (wie mit Java Flight Recorder beobachtet). Dies ist überraschend für einen scheinbar einfachen Lambda-Aufruf. Die GC-Protokolle zeigen auch viele „Cleanup“-Ereignisse und G1-Sammlungen. Warum passiert das? [img]https://i.sstatic.net/AgQUPs8J.png[/img]
GC-Protokoll: [code][2024-11-21T11:17:19.564+0400][0.009s][info][gc] Using G1 [2024-11-21T11:17:19.566+0400][0.011s][info][gc,init] Version: 17.0.12+7-LTS (release) [2024-11-21T11:17:19.566+0400][0.011s][info][gc,init] CPUs: 12 total, 12 available [2024-11-21T11:17:19.566+0400][0.011s][info][gc,init] Memory: 32448M [2024-11-21T11:17:19.566+0400][0.011s][info][gc,init] Large Page Support: Disabled [2024-11-21T11:17:19.567+0400][0.011s][info][gc,init] NUMA Support: Disabled [2024-11-21T11:17:19.567+0400][0.011s][info][gc,init] Compressed Oops: Enabled (Zero based) [2024-11-21T11:17:19.567+0400][0.011s][info][gc,init] Heap Region Size: 4M [2024-11-21T11:17:19.567+0400][0.011s][info][gc,init] Heap Min Capacity: 8M [2024-11-21T11:17:19.567+0400][0.011s][info][gc,init] Heap Initial Capacity: 508M [2024-11-21T11:17:19.568+0400][0.013s][info][gc,init] Heap Max Capacity: 8116M [2024-11-21T11:17:19.568+0400][0.013s][info][gc,init] Pre-touch: Disabled [2024-11-21T11:17:19.568+0400][0.013s][info][gc,init] Parallel Workers: 10 [2024-11-21T11:17:19.568+0400][0.013s][info][gc,init] Concurrent Workers: 3 [2024-11-21T11:17:19.568+0400][0.013s][info][gc,init] Concurrent Refinement Workers: 10 [2024-11-21T11:17:19.568+0400][0.013s][info][gc,init] Periodic GC: Disabled [2024-11-21T11:17:19.574+0400][0.019s][info][gc,metaspace] CDS archive(s) mapped at: [0x000001f851000000-0x000001f851bb0000-0x000001f851bb0000), size 12255232, SharedBaseAddress: 0x000001f851000000, ArchiveRelocationMode: 1. [2024-11-21T11:17:19.574+0400][0.019s][info][gc,metaspace] Compressed class space mapped at: 0x000001f852000000-0x000001f892000000, reserved size: 1073741824 [2024-11-21T11:17:19.574+0400][0.019s][info][gc,metaspace] Narrow klass base: 0x000001f851000000, Narrow klass shift: 0, Narrow klass range: 0x100000000 [2024-11-21T11:17:19.766+0400][0.211s][info][safepoint ] Safepoint "ICBufferFull", Time since last: 189551200 ns, Reaching safepoint: 17600 ns, Cleanup: 60000 ns, At safepoint: 7500 ns, Total: 85100 ns [2024-11-21T11:17:19.787+0400][0.232s][info][safepoint ] Safepoint "RedefineClasses", Time since last: 16989500 ns, Reaching safepoint: 3100 ns, Cleanup: 45500 ns, At safepoint: 3409200 ns, Total: 3457800 ns [2024-11-21T11:17:19.814+0400][0.259s][info][safepoint ] Safepoint "JFRCheckpoint", Time since last: 27203200 ns, Reaching safepoint: 2100 ns, Cleanup: 8500 ns, At safepoint: 1600 ns, Total: 12200 ns [2024-11-21T11:17:20.614+0400][1.058s][info][gc,start ] GC(0) Pause Young (Normal) (G1 Evacuation Pause) [2024-11-21T11:17:20.614+0400][1.059s][info][gc,task ] GC(0) Using 10 workers of 10 for evacuation [2024-11-21T11:17:20.616+0400][1.061s][info][gc,phases ] GC(0) Pre Evacuate Collection Set: 0.1ms [2024-11-21T11:17:20.616+0400][1.061s][info][gc,phases ] GC(0) Merge Heap Roots: 0.1ms [2024-11-21T11:17:20.616+0400][1.061s][info][gc,phases ] GC(0) Evacuate Collection Set: 1.5ms [2024-11-21T11:17:20.616+0400][1.061s][info][gc,phases ] GC(0) Post Evacuate Collection Set: 0.2ms [2024-11-21T11:17:20.616+0400][1.061s][info][gc,phases ] GC(0) Other: 0.4ms [2024-11-21T11:17:20.616+0400][1.061s][info][gc,heap ] GC(0) Eden regions: 6->0(7) [2024-11-21T11:17:20.616+0400][1.061s][info][gc,heap ] GC(0) Survivor regions: 0->1(1) [2024-11-21T11:17:20.616+0400][1.061s][info][gc,heap ] GC(0) Old regions: 0->0 [2024-11-21T11:17:20.616+0400][1.061s][info][gc,heap ] GC(0) Archive regions: 0->0 [2024-11-21T11:17:20.616+0400][1.061s][info][gc,heap ] GC(0) Humongous regions: 0->0 [2024-11-21T11:17:20.616+0400][1.061s][info][gc,metaspace] GC(0) Metaspace: 3984K(4096K)->3984K(4096K) NonClass: 3594K(3648K)->3594K(3648K) Class: 389K(448K)->389K(448K) [2024-11-21T11:17:20.616+0400][1.061s][info][gc ] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 24M->3M(508M) 2.466ms [2024-11-21T11:17:20.616+0400][1.061s][info][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.00s [2024-11-21T11:17:20.616+0400][1.061s][info][safepoint ] Safepoint "G1CollectForAllocation", Time since last: 799453500 ns, Reaching safepoint: 23700 ns, Cleanup: 10700 ns, At safepoint: 2637900 ns, Total: 2672300 ns [2024-11-21T11:17:21.803+0400][2.248s][info][safepoint ] Safepoint "Cleanup", Time since last: 1186781600 ns, Reaching safepoint: 25100 ns, Cleanup: 41800 ns, At safepoint: 5600 ns, Total: 72500 ns [2024-11-21T11:17:22.804+0400][3.248s][info][safepoint ] Safepoint "Cleanup", Time since last: 1000461600 ns, Reaching safepoint: 43400 ns, Cleanup: 6300 ns, At safepoint: 5000 ns, Total: 54700 ns [2024-11-21T11:17:23.805+0400][4.249s][info][safepoint ] Safepoint "Cleanup", Time since last: 1000781300 ns, Reaching safepoint: 59000 ns, Cleanup: 11500 ns, At safepoint: 11600 ns, Total: 82100 ns [2024-11-21T11:17:24.805+0400][5.249s][info][safepoint ] Safepoint "Cleanup", Time since last: 1000039000 ns, Reaching safepoint: 28800 ns, Cleanup: 7100 ns, At safepoint: 4200 ns, Total: 40100 ns [2024-11-21T11:17:26.806+0400][7.250s][info][safepoint ] Safepoint "Cleanup", Time since last: 2000881000 ns, Reaching safepoint: 24300 ns, Cleanup: 8800 ns, At safepoint: 6300 ns, Total: 39400 ns [2024-11-21T11:17:28.807+0400][9.251s][info][safepoint ] Safepoint "Cleanup", Time since last: 2000920600 ns, Reaching safepoint: 28000 ns, Cleanup: 7500 ns, At safepoint: 4100 ns, Total: 39600 ns [2024-11-21T11:17:34.810+0400][15.254s][info][safepoint ] Safepoint "Cleanup", Time since last: 6002864400 ns, Reaching safepoint: 37000 ns, Cleanup: 9400 ns, At safepoint: 8600 ns, Total: 55000 ns [2024-11-21T11:17:35.086+0400][15.531s][info][safepoint ] Safepoint "JFRCheckpoint", Time since last: 276571100 ns, Reaching safepoint: 36100 ns, Cleanup: 6400 ns, At safepoint: 58900 ns, Total: 101400 ns [2024-11-21T11:17:35.105+0400][15.549s][info][gc,heap,exit] Heap [2024-11-21T11:17:35.105+0400][15.549s][info][gc,heap,exit] garbage-first heap total 520192K, used 9809K [0x0000000604c00000, 0x0000000800000000) [2024-11-21T11:17:35.105+0400][15.549s][info][gc,heap,exit] region size 4096K, 3 young (12288K), 1 survivors (4096K) [2024-11-21T11:17:35.105+0400][15.549s][info][gc,heap,exit] Metaspace used 8222K, committed 8512K, reserved 1114112K [2024-11-21T11:17:35.105+0400][15.549s][info][gc,heap,exit] class space used 900K, committed 1024K, reserved 1048576K [/code] Beispiel 2: Vordefiniertes Lambda [code]public static void main(String[] args) { String a = "hello there"; Predicate stringPredicate = x -> x.equals(a); while (true) { something.method(stringPredicate); } } [/code] In diesem Beispiel wird das Lambda zuvor einer Variablen zugewiesen und in der Schleife wiederverwendet. Interessanterweise wird viel weniger Speicher zugewiesen (laut IDEA-Profiler-Hinweisen), aber fast die gleiche Anzahl an Safepoint-„Cleanup“-Ereignissen. [img]https://i.sstatic. net/K5Ii7JGy.png[/img]
GC-Protokoll: [code][2024-11-21T11:29:08.186+0400][0.011s][info][gc] Using G1 [2024-11-21T11:29:08.187+0400][0.013s][info][gc,init] Version: 17.0.12+7-LTS (release) [2024-11-21T11:29:08.187+0400][0.013s][info][gc,init] CPUs: 12 total, 12 available [2024-11-21T11:29:08.187+0400][0.013s][info][gc,init] Memory: 32448M [2024-11-21T11:29:08.187+0400][0.013s][info][gc,init] Large Page Support: Disabled [2024-11-21T11:29:08.187+0400][0.013s][info][gc,init] NUMA Support: Disabled [2024-11-21T11:29:08.187+0400][0.013s][info][gc,init] Compressed Oops: Enabled (Zero based) [2024-11-21T11:29:08.187+0400][0.013s][info][gc,init] Heap Region Size: 4M [2024-11-21T11:29:08.187+0400][0.013s][info][gc,init] Heap Min Capacity: 8M [2024-11-21T11:29:08.187+0400][0.013s][info][gc,init] Heap Initial Capacity: 508M [2024-11-21T11:29:08.188+0400][0.013s][info][gc,init] Heap Max Capacity: 8116M [2024-11-21T11:29:08.188+0400][0.013s][info][gc,init] Pre-touch: Disabled [2024-11-21T11:29:08.188+0400][0.013s][info][gc,init] Parallel Workers: 10 [2024-11-21T11:29:08.188+0400][0.013s][info][gc,init] Concurrent Workers: 3 [2024-11-21T11:29:08.188+0400][0.013s][info][gc,init] Concurrent Refinement Workers: 10 [2024-11-21T11:29:08.188+0400][0.013s][info][gc,init] Periodic GC: Disabled [2024-11-21T11:29:08.194+0400][0.019s][info][gc,metaspace] CDS archive(s) mapped at: [0x0000024c45000000-0x0000024c45bb0000-0x0000024c45bb0000), size 12255232, SharedBaseAddress: 0x0000024c45000000, ArchiveRelocationMode: 1. [2024-11-21T11:29:08.194+0400][0.019s][info][gc,metaspace] Compressed class space mapped at: 0x0000024c46000000-0x0000024c86000000, reserved size: 1073741824 [2024-11-21T11:29:08.194+0400][0.019s][info][gc,metaspace] Narrow klass base: 0x0000024c45000000, Narrow klass shift: 0, Narrow klass range: 0x100000000 [2024-11-21T11:29:08.391+0400][0.216s][info][safepoint ] Safepoint "ICBufferFull", Time since last: 193888700 ns, Reaching safepoint: 7400 ns, Cleanup: 69600 ns, At safepoint: 8300 ns, Total: 85300 ns [2024-11-21T11:29:08.410+0400][0.235s][info][safepoint ] Safepoint "RedefineClasses", Time since last: 16389000 ns, Reaching safepoint: 2900 ns, Cleanup: 45800 ns, At safepoint: 2560100 ns, Total: 2608800 ns [2024-11-21T11:29:08.438+0400][0.263s][info][safepoint ] Safepoint "JFRCheckpoint", Time since last: 28071700 ns, Reaching safepoint: 2800 ns, Cleanup: 11700 ns, At safepoint: 2500 ns, Total: 17000 ns [2024-11-21T11:29:09.396+0400][1.221s][info][gc,start ] GC(0) Pause Young (Normal) (G1 Evacuation Pause) [2024-11-21T11:29:09.396+0400][1.222s][info][gc,task ] GC(0) Using 10 workers of 10 for evacuation [2024-11-21T11:29:09.400+0400][1.225s][info][gc,phases ] GC(0) Pre Evacuate Collection Set: 0.1ms [2024-11-21T11:29:09.400+0400][1.225s][info][gc,phases ] GC(0) Merge Heap Roots: 0.1ms [2024-11-21T11:29:09.400+0400][1.225s][info][gc,phases ] GC(0) Evacuate Collection Set: 2.0ms [2024-11-21T11:29:09.400+0400][1.225s][info][gc,phases ] GC(0) Post Evacuate Collection Set: 0.4ms [2024-11-21T11:29:09.400+0400][1.225s][info][gc,phases ] GC(0) Other: 0.5ms [2024-11-21T11:29:09.400+0400][1.225s][info][gc,heap ] GC(0) Eden regions: 6->0(7) [2024-11-21T11:29:09.400+0400][1.225s][info][gc,heap ] GC(0) Survivor regions: 0->1(1) [2024-11-21T11:29:09.400+0400][1.225s][info][gc,heap ] GC(0) Old regions: 0->0 [2024-11-21T11:29:09.400+0400][1.225s][info][gc,heap ] GC(0) Archive regions: 0->0 [2024-11-21T11:29:09.400+0400][1.225s][info][gc,heap ] GC(0) Humongous regions: 0->0 [2024-11-21T11:29:09.400+0400][1.225s][info][gc,metaspace] GC(0) Metaspace: 7360K(7552K)->7360K(7552K) NonClass: 6565K(6656K)->6565K(6656K) Class: 794K(896K)->794K(896K) [2024-11-21T11:29:09.400+0400][1.225s][info][gc ] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 24M->3M(508M) 3.217ms [2024-11-21T11:29:09.400+0400][1.225s][info][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.00s [2024-11-21T11:29:09.400+0400][1.225s][info][safepoint ] Safepoint "G1CollectForAllocation", Time since last: 958423000 ns, Reaching safepoint: 23600 ns, Cleanup: 37100 ns, At safepoint: 3297100 ns, Total: 3357800 ns [2024-11-21T11:29:10.419+0400][2.244s][info][safepoint ] Safepoint "Cleanup", Time since last: 1019081500 ns, Reaching safepoint: 15700 ns, Cleanup: 21900 ns, At safepoint: 5300 ns, Total: 42900 ns [2024-11-21T11:29:11.420+0400][3.244s][info][safepoint ] Safepoint "Cleanup", Time since last: 1000396700 ns, Reaching safepoint: 13700 ns, Cleanup: 8300 ns, At safepoint: 4800 ns, Total: 26800 ns [2024-11-21T11:29:12.420+0400][4.245s][info][safepoint ] Safepoint "Cleanup", Time since last: 1000880300 ns, Reaching safepoint: 25700 ns, Cleanup: 10100 ns, At safepoint: 66000 ns, Total: 101800 ns [2024-11-21T11:29:13.421+0400][5.245s][info][safepoint ] Safepoint "Cleanup", Time since last: 1000087200 ns, Reaching safepoint: 18300 ns, Cleanup: 13100 ns, At safepoint: 5200 ns, Total: 36600 ns [2024-11-21T11:29:14.421+0400][6.246s][info][safepoint ] Safepoint "Cleanup", Time since last: 1000750200 ns, Reaching safepoint: 16000 ns, Cleanup: 8300 ns, At safepoint: 28600 ns, Total: 52900 ns [2024-11-21T11:29:15.422+0400][7.247s][info][safepoint ] Safepoint "Cleanup", Time since last: 1000323100 ns, Reaching safepoint: 13500 ns, Cleanup: 9500 ns, At safepoint: 566000 ns, Total: 589000 ns [2024-11-21T11:29:17.423+0400][9.248s][info][safepoint ] Safepoint "Cleanup", Time since last: 2000973400 ns, Reaching safepoint: 17600 ns, Cleanup: 6200 ns, At safepoint: 4500 ns, Total: 28300 ns [2024-11-21T11:29:23.427+0400][15.251s][info][safepoint ] Safepoint "Cleanup", Time since last: 6003316900 ns, Reaching safepoint: 16300 ns, Cleanup: 13000 ns, At safepoint: 11100 ns, Total: 40400 ns [2024-11-21T11:29:23.858+0400][15.683s][info][safepoint ] Safepoint "JFRCheckpoint", Time since last: 431903500 ns, Reaching safepoint: 12800 ns, Cleanup: 10400 ns, At safepoint: 44800 ns, Total: 68000 ns [2024-11-21T11:29:23.876+0400][15.701s][info][gc,heap,exit] Heap [2024-11-21T11:29:23.876+0400][15.701s][info][gc,heap,exit] garbage-first heap total 520192K, used 7237K [0x0000000604c00000, 0x0000000800000000) [2024-11-21T11:29:23.876+0400][15.701s][info][gc,heap,exit] region size 4096K, 2 young (8192K), 1 survivors (4096K) [2024-11-21T11:29:23.876+0400][15.701s][info][gc,heap,exit] Metaspace used 8206K, committed 8448K, reserved 1114112K [2024-11-21T11:29:23.876+0400][15.701s][info][gc,heap,exit] class space used 900K, committed 1024K, reserved 1048576K [/code] [b]Fragen[/b] [list] [*]Warum führt Beispiel 1 zu deutlich mehr Speicherzuweisung? im Vergleich zu Beispiel 2? [list] Wird bei jedem Aufruf des Inline-Lambda ein neues Lambda-Objekt erstellt? [*]Wie ist das? Speicher für Lambdas in der JVM zugewiesen? [/list]
[*]In beiden Beispielen zeigen die GC-Protokolle viele „Cleanup“-Ereignisse. [list] Was genau wird während dieser Ereignisse bereinigt? [*]Hängt es mit Lambdas, Thread-lokalem Speicher oder etwas anderem zusammen? [/list]
[*]Gibt es eine Möglichkeit, Lambdas in einem [b]GC-freien System zu verwenden? Stil[/b], so dass kein Müll erzeugt wird, wenn sie wiederholt aufgerufen werden? [list] Wenn nicht, würde es helfen, bei anonymen Klassen oder funktionalen Schnittstellen zu bleiben?< /li> [/list]
[*]Wie kann ich dies weiter profilieren und debuggen, um das interne Speicherverhalten von Lambdas zu verstehen?
Ich habe einen Datentyp, dessen Lebensdauer undefiniert ist. Daher ist es eine Klasse. Allerdings wird es sehr oft erstellt, was dazu führt, dass es ständig Speicher belegt. Es hat auch ziemlich viel...
Ich versuche, mich mit einem Teil des folgenden Textes auseinanderzusetzen, der in The C++ Programming Language, vierte Ausgabe von Bjarne Stroustrup (TC++PL) zu finden ist.
Ich experimentiere mit der Definition von DataClasses zum Enthaltenden von CTypes -Objekten. Ich habe drei Klassen definiert; Zwei davon werden als Attribute zum dritten verwendet:...
und zusätzliche Blöcke werden ebenfalls geladen, wenn Sie auf die Schaltfläche klicken. Ich kann nicht herausfinden, wie ich dafür sorgen kann, dass...