Skip to content

Commit 60905ec

Browse files
authored
Merge pull request #313 from graalvm/ni-demos-refactoring-10
[GR-60094] Add demo for Optimize Memory Footprint of a Native Executable guide.
2 parents 4d10d39 + 691cc97 commit 60905ec

File tree

5 files changed

+152
-0
lines changed

5 files changed

+152
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: native-image/optimize-memory
2+
on:
3+
push:
4+
paths:
5+
- 'native-image/optimize-memory/**'
6+
- '.github/workflows/native-image-optimize-memory.yml'
7+
pull_request:
8+
paths:
9+
- 'native-image/optimize-memory/**'
10+
- '.github/workflows/native-image-optimize-memory.yml'
11+
schedule:
12+
- cron: "0 0 1 * *" # run every month
13+
workflow_dispatch:
14+
permissions:
15+
contents: read
16+
jobs:
17+
run:
18+
name: Run 'native-image/optimize-memory'
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 15
21+
strategy:
22+
matrix:
23+
java-version: ['21', '24-ea']
24+
steps:
25+
- uses: actions/checkout@v4
26+
- uses: graalvm/setup-graalvm@v1
27+
with:
28+
java-version: ${{ matrix.java-version }}
29+
distribution: 'graalvm'
30+
github-token: ${{ secrets.GITHUB_TOKEN }}
31+
native-image-job-reports: 'true'
32+
- name: Run 'native-image/optimize-memory'
33+
run: |
34+
cd native-image/optimize-memory
35+
./run.sh
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.class
2+
testgc-serial
3+
testgc-g1
4+
testgc-epsilon
5+
testgc-maxheapset-g1
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Optimize Memory Footprint of a Native Executable
2+
3+
You can find the steps to run this demo on [the website](https://www.graalvm.org/jdk24/reference-manual/native-image/guides/optimize-memory-footprint/).
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
import java.util.ArrayDeque;
42+
43+
public class StringManipulation {
44+
45+
public static void main(String[] args) {
46+
System.out.println("Starting string manipulation GC stress test...");
47+
48+
// Parse arguments
49+
int iterations = 1000000;
50+
int numKeptAliveObjects = 100000;
51+
if (args.length > 0) {
52+
iterations = Integer.parseInt(args[0]);
53+
}
54+
if (args.length > 1) {
55+
numKeptAliveObjects = Integer.parseInt(args[1]);
56+
}
57+
58+
ArrayDeque<String[]> aliveData = new ArrayDeque<String[]>(numKeptAliveObjects + 1);
59+
for (int i = 0; i < iterations; i++) {
60+
// Simulate log entry generation and log entry splitting. The last n entries are kept in memory.
61+
String base = "log-entry";
62+
StringBuilder builder = new StringBuilder(base);
63+
64+
for (int j = 0; j < 100; j++) {
65+
builder.append("-").append(System.nanoTime());
66+
}
67+
68+
String logEntry = builder.toString();
69+
String[] parts = logEntry.split("-");
70+
71+
aliveData.addLast(parts);
72+
if (aliveData.size() > numKeptAliveObjects) {
73+
aliveData.removeFirst();
74+
}
75+
76+
// Periodically log progress
77+
if (i % 100000 == 0) {
78+
System.out.println("Processed " + i + " log entries");
79+
}
80+
}
81+
82+
System.out.println("String manipulation GC stress test completed: " + aliveData.hashCode());
83+
}
84+
}

native-image/optimize-memory/run.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bash
2+
set -ex
3+
4+
# Compile and run the application on HotSpot
5+
javac StringManipulation.java
6+
/usr/bin/time java StringManipulation 500000 50000
7+
8+
# Build a Native Image with Serial GC (default)
9+
native-image -Ob -o testgc-serial StringManipulation
10+
/usr/bin/time ./testgc-serial 500000 50000 -XX:+PrintGC
11+
12+
# Build a Native Image with G1 GC
13+
native-image -Ob --gc=G1 -o testgc-g1 StringManipulation
14+
/usr/bin/time ./testgc-g1 500000 50000 -XX:+PrintGC
15+
16+
# Build a Native Image with Epsilon GC
17+
native-image -Ob --gc=epsilon -o testgc-epsilon StringManipulation
18+
/usr/bin/time ./testgc-epsilon 100000 50000
19+
20+
# Build a Native Image Setting the Maximum Heap Size
21+
# At run time
22+
/usr/bin/time ./testgc-g1 -Xmx512m 500000 50000
23+
# At build Time
24+
native-image -Ob --gc=G1 -R:MaxHeapSize=512m -o testgc-maxheapset-g1 StringManipulation
25+
/usr/bin/time ./testgc-maxheapset-g1 500000 50000

0 commit comments

Comments
 (0)