1 source

  • Source: Java Virtual Machine JVM Fault Diagnosis and Performance Optimization — Ge Yiming
  • Chapter: Chapter three

This article is some notes of chapter 3.

2 GCLog:-Xlog:gc

To PrintGC logs, add the -xlog: GC parameter (JDK8 and below use -xx :+PrintGC). After GC printing is enabled, each GC will print the following log:

[0.126s][INFO][GC] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 25M->0M(502M) 1.902ms [0.205s][INFO][GC] GC(1) Pause Young (Normal) (G1 Evacuation Pause) 300M->0M(502M) 4.174ms [0.236s][info][GC] GC(2) Pause Young (Normal) (G1 Evacuation Pause) 300M->0M(502M) 2.067ms [0.268s][info][GC] GC(3) Pause Young (Normal) (G1 Evacuation Pause) 300 m - > 0 m (502 m) 2.362 msCopy the code

Where, the beginning time indicates the time when GC occurs, 25M->0M(502M) indicates:

  • GCBefore, the heap usage is25M
  • GCAfter, the heap usage is0M
  • The sum of the heap space is approximately502M

The time at the end indicates the duration of the GC.

-xlog :gc* (-xx :+PrintGCDetails) -xlog :gc* (-xlog :gc*)

[0.137s][info][GC,start] GC(0) Pause Young (Normal) (G1 Evacuation Pause) [0.138s][INFO][GC,task] GC(0) Using 10 workers of 10forEvacuation [0.147s][info][GC, Phases] GC(0) Pre Evacuate Collection Set 37 ms [0.47 s][info][GC, Phases] gc (0) Evacuate Collection Set: 37 ms [0.147s][info][GC, Phases] GC(0) Post Evacuate Collection Set: 0.1 ms [0.147s][info][GC, Phases] GC(0) Other: 0.8ms [0.147s][info][GC,heap] GC(0) Eden Regions: 25->0(300) [0.147s][info][GC,heap] GC(0) Survivor regions: 0->1(4) [0.147s][info][GC,heap] GC(0) Old Regions: 0->0 [0.147s][info][GC,heap] GC(0) Humongous Regions: 0->0 [0.141s][info][GC,metaspace] GC(0) metaspace: 6633K->6633K(1056768K) [0.147s][info][GC] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 25M->0M(502M) 9.878ms [info][GC, CPU] GC(0) User=0.05s Sys=0.00s Real=0.01sCopy the code
  • Time at the beginning of the line: the time at which the event occurred
  • GC(0): This is the first timeGCAnd then there will beGC(1),GC(2)
  • Pause Young (Normal): this timeGCReclaiming the New generation
  • Using 10 workers: Uses 10 worker threads
  • Pre Evacuate Collection Set/Evacuate Collection Set/Post Evacuate/OtherSaid:G1Garbage collection marks, the time spent in different stages of the cleanup algorithm
  • Eden/Survivor/Old/Humongous/Metaspace: Represent separatelyEden area,Live area,Old district,Giant object region(that is, the region of a very, very large object),Metadata areainGCFront and back size
  • 25M-0M(502M):GCBefore the heap usage25M.GCafter0M, the available heap space is502M
  • User/Sys/Real: Represent separatelyCPU usage in user mode,System CPU Usage,GC true experience time

If you want to see more comprehensive heap information, you can use Visual VM, which will be described in a subsequent article.

Alternatively, if you want to persist logs, you can use -xlog :gc:gc.log.

3 Printing system parameters

The -xx :+PrintVMOptinos argument prints the explicit arguments received at runtime, while -xx :+PrintCommandLineFlags prints the implicit and explicit arguments passed to the JVM:

The other argument is -xx :+PrintFlagsFinal, which prints the values of all system parameters (there are a lot of them) :

4 parameters

4.1 Maximum heap and initial heap parameters

When the Java process starts, the virtual machine is allocated an initial heap space, and the initial size of this space can be specified using the -xms parameter. Generally speaking, the virtual machine runs within the initial heap space as much as possible, but if the initial heap space runs out, the virtual machine expands the heap space up to the maximum heap space, which can be specified using the -xmx parameter.

Let’s test this out with some code:

public class Main {

    public static void main(String[] args){
        printMemory();

        byte [] bytes = new byte[1*1024*1024];
        System.out.println("Allocate 1024 KB array");
        printMemory();

        bytes = new byte[4*1024*1024];
        System.out.println("Allocate 4096 KB array");
        printMemory();
    }

    public static void printMemory(a){
        System.out.println();
        System.out.println("Max memory = " + Runtime.getRuntime().maxMemory() / 1024+ " KB");
        System.out.println("Free memory = "+Runtime.getRuntime().freeMemory()/1024+ " KB");
        System.out.println("Total memory = " + Runtime.getRuntime().totalMemory()/ 1024+ " KB"); System.out.println(); }}Copy the code

Parameters:

-Xmx20m
-Xms5m
-XX:+PrintCommandLineFlags
-Xlog:gc*
-XX:+UseSerialGC
Copy the code

Output:

-XX:InitialHeapSize=5242880 -XX:MaxHeapSize=20971520 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -xx :+UseSerialGC [0.002s][info][GC] Using Serial [0.002s][info][GC,heap, coOPS] Heap address: 0x00000000fec00000, size: 20 MB, Compressed Oops mode: 32-bit [0.110s][info][GC,start] GC(0) Pause Young (Allocation Failure) [0.112s][info][GC,heap] GC(0) DefNew: 1664K->192K(1856K) [0.112s][info][GC,heap] GC(0) Tenured: 0K->598K(4096K) [0.112s][info][GC,metaspace] GC(0) metaspace: 6436K->6436K(1056768K) [0.112s][info][GC] GC(0) Pause Young (Allocation Failure) 1M->0M(5M) 2.069ms [0.112s][info ][GC, CPU] GC(0) User=0.00s Sys=0.00s Real=0.01s Max Memory = 19840 KB Free memory = 4797 KB Total memory = 5952 KB Allocate 1024 KB Array Max Memory = 19840 KB Free memory = 3773 KB Total memory = 5952 KB [0.128s][info][GC,start] Allocate 1024 KB Array Max Memory = 19840 KB Free memory = 3773 KB Total memory = 5952 KB [0.128s][info][GC,start] GC(1) Pause Young (Allocation Failure) [0.125s][info][GC,start] GC(2) Pause Full (Allocation Failure) [0.125s][info [GC, Phases, Start] GC(2) Phase 1: Mark Live Objects [0.130s][info] GC(2) Phase 1: [Info][GC, Phases, Start] GC(2) Phase 2: Compute New Object addresses [0.130s][info][GC, Phases] GC(2) Phase 2: Compute New object addresses [0.130s][info][GC, Phases] GC(2) Phase 2: Compute New object addresses 0.235ms [0.130s][info][GC, Phases,start] GC(2) Phase 3: Adjustment [0.131s][info][GC, Phases] GC(2) Phase 3: Adjustment 0.624ms [0.131s][INFO][GC, Phases,start] GC(2) Phase 4: Move Objects [0.131s][info][GC, Phases] GC(2) Phase 4: Move Objects 0.042ms [0.131s][info][GC] GC(2) Pause Full (Allocation Failure) 1M->1M(5M) 2.335ms [0.131s][info [gc,heap] gc (1) DefNew: 1579K->0K(1856K) [0.131s][info][GC,heap] GC(1) Tenured: 598K->1899K(4096K) [0.131s][info][GC,metaspace] 6624K->6624K(1056768K) [0.131s][info][GC] GC(1) Pause Young (Allocation Failure) 2M->1M(5M) 3.636ms [0.131s][info [GC, CPU] GC(1) User=0.00s Sys=0.01s Real=0.00s Allocate 4096 KB Array Max memory = 19840 KB Free memory = 4087 KB Total memory = 10116 KB [0.133s][info][GC,heap,exit] Heap [s] 0.133 [info] [gc, Heap,exit] def new generation total 1920K, used 44K [0x00000000fec00000, 0x00000000fee10000, 0 x00000000ff2a0000) [s] 0.133 [info] [gc, heap,exit] Eden Space 1728K, 2% used [0x00000000Fec00000, 0x00000000Fec0B198, 0x00000000Fedb0000) [0.133s][info][GC,heap,exit] from space 192K, 0% used [0x00000000FeDB0000, 0x00000000Fedb0000, 0x00000000Fede0000) [0.133s][info][gc,heap,exit] to space 192K, 0% used [0x00000000Fede0000, 0x00000000Fede0000, 0x00000000fee10000) [0.133s][info][gc,heap,exit] tenured generation total 8196K, used 5995K [0x00000000ff2a0000, 0x00000000ffaa1000, 0 x0000000100000000) [s] 0.133 [info] [gc, heap,exit] the space 8196K, 73% used [0x00000000ff2a0000, 0x00000000ff87aed0, 0x00000000ff87b000, 0 x00000000ffaa1000) [s] 0.133 [info] [gc, heap,exit] Metaspace used 6640K, capacity 6723K, committed 7040K, reserved 1056768K [0.133s][info][GC,heap,exit   ]   class space    used 590K, capacity 623K, committed 640K, reserved 1048576K
Copy the code

The maximum memory is specified by -xx :MaxHeapSize. This value is the value of -xmx, which is 20 * 1024 * 1024, and the maximum available memory printed is 20316160, which is less than the set value. This is because the memory allocated to the heap is not the same concept as the actual available memory. The virtual machine partition manages the heap space, and different partitions use different reclaim algorithms. Some algorithms use the space-for-time strategy, so there will be a loss. The final result is that the actual available memory will waste space equal to the size of from/to.

[s] 0.139 [info] [gc, heap,exit   ]   from space 192K,   0% used [0x00000000fedb0000, 0x00000000fedb0000, 0x00000000fede0000)
Copy the code

The size of the virtual machine is 192k, but the maximum available memory is 19840K + 192K from = 20032K, not the allocated memory 20480K. This is because the virtual machine aligns the maximum available memory with the aligned FROM/TO to to get the allocated memory size.

In addition, the print shows that the initial run of free memory 4797K, allocate a 1024K array, free memory 3773K, which fits, then allocate 4096K, because the memory is insufficient, expand the heap space and then allocate again, the expanded heap size is 10116K.

In practice, you can set -xms to be the same as -xmx to reduce GC times at run time and improve performance.

4.2 Cenozoic Parameters

-Xmn can set the size of the new generation. Setting a larger new generation will reduce the size of the old age. This parameter has a great impact on heap GC, generally set to 1/3 to 1/4 of the heap space. Parameter -xx :SurvivorRatio can be used to set the ratio between Eden and FROM /to. It is equivalent to:

-XX:SurvivorRatio=eden/from=eden/to
Copy the code

A simple example is as follows:

public static void main(String[] args){
    byte [] b = null;
    for (int i = 0; i < 10; i++) {
        b = new byte[1*1024*1024]; }}Copy the code

Parameters:

-Xmx20m
-Xms20m
-Xmn1m
-XX:SurvivorRatio=2
-Xlog:gc*
-XX:+UseSerialGC
Copy the code

Output:

[0.002s][info][GC] Using Serial [0.002s][info][GC,heap, Coops] Heap Address: 0x00000000fec00000, size: 20 MB, Compressed Oops mode: 32-bit [0.042s][info][GC,start] GC(0) Pause Young (Allocation Failure) [0.044s][info][GC,heap] GC(0) DefNew: 512K->256K(768K) [0.044s][info][GC,heap] GC(0) Tenured: 0K->172K(19456K) [0.044s][info][GC,metaspace] GC(0) metaspace: 3871K->3871K(1056768K) [0.044s][info][GC] GC(0) Pause Young (Allocation Failure) 0M->0M(19M) 1.617ms [0.044s][info][GC, CPU] GC(0) User=0.01s Sys=0.00s Real=0.00s [0.064s][info][GC,start] GC(1) Pause Young (Allocation [info][GC,heap] GC(1) DefNew: 767K->76K(768K) [0.065s][info][GC,heap] GC(1) Tenured: 172K->425K(19456K) [0.065s][info][GC,metaspace] GC(1) metaspace: 4518K->4518K(1056768K) [0.065s][info][GC] GC(1) Pause Young (Allocation Failure) 0M->0M(19M) 0.870ms [0.065s][info][GC, CPU] GC(1) User=0.00s Sys=0.00s Real=0.00s [0.093s][info][GC,heap, heap, heap, heap, heap, heapexit] Heap [s] 0.093 [info] [gc, Heap,exit] def new generation total 768K, used 562K [0x00000000fec00000, 0x00000000fed00000, 0 x00000000fed00000) [s] 0.093 [info] [gc, heap,exit ]   eden space 512K,  94% used [0x00000000fec00000, 0x00000000fec79730, 0x00000000fec80000)
[0.093s][info][gc,heap,exit ]   from space 256K,  29% used [0x00000000fec80000, 0x00000000fec93260, 0x00000000fecc0000)
[0.093s][info][gc,heap,exit ]   to   space 256K,   0% used [0x00000000fecc0000, 0x00000000fecc0000, 0x00000000fed00000)
[0.093s][info][gc,heap,exit] tenured generation total 19456K, used 10665K [0x00000000fed00000, 0x0000000100000000, 0 x0000000100000000) [s] 0.093 [info] [gc, heap,exit] the space 19456K, 54% used [0x00000000fed00000, 0x00000000ff76a630, 0x00000000ff76a800, 0 x0000000100000000) [s] 0.093 [info] [gc, heap,exit ]  Metaspace       used 6190K, capacity 6251K, committed 6528K, reserved 1056768K
[0.093s][info][gc,heap,exit ]   class space    used 535K, capacity 570K, committed 640K, reserved 1048576K
Copy the code

The ratio of Eden area to FROM area is 2:1, so Eden area is 512K, the total available size of new generation is 512K+256K=768K, and the total size of new generation is 512K+256K+256K=1M. Since Eden area cannot accommodate the allocation of 1MB array, the generation GENERATION GC is triggered. All arrays are allocated in the old age.

If -xmn7m is used (other parameters remain unchanged), the output is as follows:

[0.003s][info][GC] Using Serial [0.003s][info][GC,heap, Coops] Heap Address: 0x00000000fec00000, size: 20 MB, Compressed Oops mode: 32-bit [0.096s][info][GC,start] GC(0) Pause Young (Allocation Failure) [0.097s][info][GC,heap] GC(0) DefNew: 2684K->1752K(5376K) [0.097s][info][GC,heap] GC(0) 0K->0K(13312K) [0.097s][info][GC,metaspace] GC(0) metaspace: 5929K->5929K(1056768K) [0.097s][info][GC] GC(0) Pause Young (Allocation Failure) 2M->1M(18M) 1.350ms [0.097s][info][GC, CPU] GC(0) User=0.00s Sys=0.00s Real=0.00s [0.098s][info][GC,start] GC(1) Pause Young (Allocation [info][GC,heap] GC(1) DefNew: 4928K->1024K(5376K) [0.099s][info][GC,heap] GC(1) Tenured: 0K->727K(13312K) [0.099s][info][GC,metaspace] GC(1) metaspace: 5996K->5996K(1056768K) [0.099s][info][GC] GC(1) Pause Young (Allocation Failure) 4M->1M(18M) 1.142ms [0.099s][info][GC, CPU] GC(1) User=0.01s Sys=0.00s Real=0.00s [0.100s][info][GC,start] GC(2) Pause Young (Allocation [info][GC,heap] GC(2) DefNew: 4180K->1024K(5376K) [0.100s][info][GC,heap] GC(2) Tenured: 727K->728K(13312K) [0.100s][info][GC,metaspace] 6008K->6008K(1056768K) [0.100s][info][GC] GC(2) Pause Young (Allocation Failure) 4M->1M(18M) 0.190ms [0.100s][info][GC, CPU] GC(2) User=0.00s Sys=0.00s Real=0.00s [0.100s][info][GC,heap,exit] Heap [s] 0.100 [info] [gc, Heap,exit] def new generation total 5376K, used 4211K [0x00000000fec00000, 0x00000000ff300000, 0 x00000000ff300000) [s] 0.100 [info] [gc, heap,exitUsed [0x00000000Fec00000, 0x00000000FeF1CC00, 0x00000000FeF80000) [0.100s][info][GC,heap,exit ]   from space 1792K,  57% used [0x00000000ff140000, 0x00000000ff2402a0, 0x00000000ff300000)
[0.100s][info][gc,heap,exit ]   to   space 1792K,   0% used [0x00000000fef80000, 0x00000000fef80000, 0x00000000ff140000)
[0.100s][info][gc,heap,exit] tenured generation total 13312K, used 728K [0x00000000ff300000, 0x0000000100000000, 0 x0000000100000000) [s] 0.100 [info] [gc, heap,exit] the space 13312K, 5% used [0x00000000ff300000, 0x00000000ff3b61f8, 0x00000000ff3b6200, 0 x0000000100000000) [s] 0.100 [info] [gc, heap,exit ]  Metaspace       used 6034K, capacity 6091K, committed 6272K, reserved 1056768K
[0.100s][info][gc,heap,exit ]   class space    used 518K, capacity 538K, committed 640K, reserved 1048576K
Copy the code

Under this parameter, there is enough space in Eden area, and all arrays are allocated in Eden area, but there is not enough space to reserve 10M space, so GC is generated. Each space application also wastes the space applied last time, and the memory is effectively reclaimed in the new generation GC. The final result is that all memory allocation is carried out in the new generation GC. Only in the GC process some of the new generation objects are promoted to the old generation.

To increase the new generation again, use -xmn15m-xx :SurvivorRatio=8 (other parameters remain unchanged), output is as follows:

[0.003s][info][GC] Using Serial [0.003s][info][GC,heap, Coops] Heap Address: 0x00000000fec00000, size: 20 MB, Compressed Oops mode: 32-bit start [0.097s][info][GC,start] GC(0) Pause Young (Allocation Failure) [0.099s][info][GC,heap] GC(0) DefNew: 11416K->1471K(13696K) [0.099s][info][GC,heap] GC(0) Tenured: 0K->294K(5312K) [0.099s][info][GC,metaspace] GC(0) metaspace: 6103K->6103K(1056768K) [0.099s][info][GC] GC(0) Pause Young (Allocation Failure) 11M->1M(18M) 2.322ms [0.099s][info][GC, CPU] GC(0) User=0.00s Sys=0.00s Real=0.01s end [0.099s][info][gc,heap, heap, heap, heap, heapexit] Heap [s] 0.099 [info] [gc, Heap,exit] def new generation total 13696K, used 2934K [0x00000000fec00000, 0x00000000ffad0000, 0 x00000000ffad0000) [s] 0.099 [info] [gc, heap,exit ]   eden space 12224K,  11% used [0x00000000fec00000, 0x00000000fed6d908, 0x00000000ff7f0000)
[0.099s][info][gc,heap,exit ]   from space 1472K,  99% used [0x00000000ff960000, 0x00000000ffacfff8, 0x00000000ffad0000)
[0.099s][info][gc,heap,exit ]   to   space 1472K,   0% used [0x00000000ff7f0000, 0x00000000ff7f0000, 0x00000000ff960000)
[0.099s][info][gc,heap,exit] tenured generation total 5312K, used 294K [0x00000000ffad0000, 0x0000000100000000, 0 x0000000100000000) [s] 0.099 [info] [gc, heap,exit] the space 5312K, 5% used [0x00000000ffad0000, 0x00000000ffb19960, 0x00000000ffb19a00, 0 x0000000100000000) [s] 0.099 [info] [gc, heap,exit ]  Metaspace       used 6164K, capacity 6251K, committed 6528K, reserved 1056768K
[0.099s][info][gc,heap,exit ]   class space    used 532K, capacity 570K, committed 640K, reserved 1048576K
Copy the code

It can be seen that the new generation uses 15M space, and the Eden area occupies 12288K, which fully meets the need of 10MB, without GC (the LOG GC is only generated after the end of the for cycle, and 10M is recovered at one time).

In actual work, reasonable Settings should be made according to the characteristics of the system. The basic strategies are as follows:

  • Save as much as possible for the new generation
  • Decrease agingGCThe number of

Alternatively, use -xx :NewRatio= old age/New age to specify the ratio between the new and old age, as in the argument:

-Xmx20m
-Xms20m
-XX:NewRatio=2
-Xlog:gc*
-XX:+UseSerialGC
Copy the code

Output:

[0.005s][info][GC] Using Serial [0.005s][info][GC,heap, Coops] Heap Address: 0x00000000fec00000, size: 20 MB, Compressed Oops mode: 32-bit [0.096s][info][GC,start] GC(0) Pause Young (Allocation Failure) [0.097s][info][GC,heap] GC(0) DefNew: 4852K->639K(6144K) [0.097s][info][GC,heap] GC(0) Tenured: 0K-> 13696K [0.097s][info][GC,metaspace] GC(0) metaspace: 5905K->5905K(1056768K) [0.097s][info][GC] GC(0) Pause Young (Allocation Failure) 4M->1M(19M) 1.413ms [0.097s][info][GC, CPU] GC(0) User=0.00s Sys=0.00s Real=0.00s [0.098s][info][GC,start] GC(1) Pause Young (Allocation [info][GC,heap] GC(1) DefNew: 5920K->0K(6144K) [0.099s][info][GC,heap] GC(1) Tenured: [info][GC,metaspace] GC(1) metaspace: 5970K->5970K(1056768K) [0.099s][info][GC] GC(1) Pause Young (Allocation Failure) 6M->2M(19M) 1.129ms [s] 0.099 [info] [gc, CPU] gc (1) the User s Sys = = 0.00 0.01 s Real = 0.00 s 0.100 [s] [info] [gc, heap,exit] Heap [s] 0.100 [info] [gc, Heap,exit] def new generation total 6144K, used 2238K [0x00000000fec00000, 0x00000000ff2a0000, 0 x00000000ff2a0000) [s] 0.100 [info] [gc, heap,exit ]   eden space 5504K,  40% used [0x00000000fec00000, 0x00000000fee2f690, 0x00000000ff160000)
[0.100s][info][gc,heap,exit ]   from space 640K,   0% used [0x00000000ff160000, 0x00000000ff160398, 0x00000000ff200000)
[0.100s][info][gc,heap,exit ]   to   space 640K,   0% used [0x00000000ff200000, 0x00000000ff200000, 0x00000000ff2a0000)
[0.100s][info][gc,heap,exit] tenured generation total 13696K, used 2776K [0x00000000ff2a0000, 0x0000000100000000, 0 x0000000100000000) [s] 0.100 [info] [gc, heap,exit] the space 13696K, 20% used [0x00000000ff2a0000, 0x00000000ff556250, 0x00000000ff556400, 0 x0000000100000000) [s] 0.100 [info] [gc, heap,exit ]  Metaspace       used 5998K, capacity 6091K, committed 6272K, reserved 1056768K
[0.100s][info][gc,heap,exit ]   class space    used 517K, capacity 538K, committed 640K, reserved 1048576K
Copy the code

The size of the heap is 20M, and the ratio of the new generation to the old generation is 1:2, so the size of the new generation is about 7M, and the size of the old generation is 13M. When allocating 1M, due to the lack of space from/to, two 1MB arrays enter the old age.

4.3 Heap overflow processing

If the Java program is running out of heap space, an out of memory error, commonly known as OOM, will be thrown. Want to analyze the reason, you can use the parameter – XX: + HeapDumpOnOutOfMemoryError, can export the entire heap information in memory, also used – XX: HeapDumpPath, designated export heap storage path, examples are as follows:

public static void main(String[] args){
    List<byte[]> list = new ArrayList<>();
    for (int i = 0; i < 25; i++) {
        list.add(new byte[1*1024*1024]); }}Copy the code

Parameters:

-Xmx20m
-Xms5m
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=out.dump
Copy the code

This example allocates 25M of memory, but the heap is only 20M, throws OOM, and saves the file in out.dump. Note that the file is a binary file, and you need to use professional tools (such as MAT) to view it.

5 Non-heap parameters

5.1 method area

Starting with JDK8, the permanent area is removed and a new metadata area is used to hold the metadata of classes. By default, the metadata area is limited by the available memory of the system, but you can still specify the maximum available value of the permanent area using -xx :MaxMetaspaceSize.

5.2 the stack

The stack is a space that is private to each thread, and you can specify the stack size of a thread using -xss, as I did in my previous article.

5.3 Direct Memory

Direct memory skips the Java heap and allows programs to access the native heap space directly, making it somewhat faster to access the memory space. The maximum available direct memory can be set to -xx :MaxDirectMemorySize. If this is not set, the default value is the maximum heap space, that is, the value of -xmx. When the direct memory usage reaches the maximum value, GC will be triggered.

Let’s test the speed of direct memory and heap:

public class Main {

    public static final int count = 1000000;

    public static void directAccess(a){
        long start = System.currentTimeMillis();
        ByteBuffer b = ByteBuffer.allocateDirect(500);
        for(int i=0; i<count; ++i){for (int j = 0; j < 99; j++) {
                b.putInt(j) ;
            }
            b.flip();
            for (int j = 0; j < 99; j++) {
                b.getInt();
            }
            b.clear();
        }
        long end = System.currentTimeMillis();
        System.out.println("Direct access: "+(end-start)+" ms");
    }

    public static void bufferAccess(a){
        long start = System.currentTimeMillis();
        ByteBuffer b = ByteBuffer.allocate(500);
        for(int i=0; i<count; ++i){for (int j = 0; j < 99; j++) {
                b.putInt(j) ;
            }
            b.flip();
            for (int j = 0; j < 99; j++) {
                b.getInt();
            }
            b.clear();
        }
        long end = System.currentTimeMillis();
        System.out.println("Buffer access: "+(end-start)+" ms");
    }


    public static void main(String[] args){ directAccess(); bufferAccess(); directAccess(); bufferAccess(); }}Copy the code

Output (without any parameters) :

Direct access: 167 ms
Buffer access: 70 ms
Direct access: 176 ms
Buffer access: 67 ms
Copy the code

Direct memory is faster to access than heap memory, but has the disadvantage of being slow to request:

public static void directAllocate(a){
    long start = System.currentTimeMillis();
    for (int i = 0; i < count; i++) {
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1000);
    }
    long end = System.currentTimeMillis();
    System.out.println("Direct allocate: "+(end-start)+" ms");
}

public static void bufferAllocate(a){
    long start = System.currentTimeMillis();
    for (int i = 0; i < count; i++) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(1000);
    }
    long end = System.currentTimeMillis();
    System.out.println("Buffer allocate: "+(end-start)+" ms");
}


public static void main(String[] args){
    directAllocate();
    bufferAllocate();

    directAllocate();
    bufferAllocate();
}
Copy the code

Output:

Direct allocate: 867 ms
Buffer allocate: 287 ms
Direct allocate: 676 ms
Buffer allocate: 208 ms
Copy the code

To put it simply, direct memory is suitable for scenarios with few requests and frequent access. Direct memory is not suitable for scenarios that require frequent memory requests.