Skip to content

Commit ba4f045

Browse files
committed
[GR-63280] [GR-63269] In the native-image output, format bytes plainly without fractions.
PullRequest: graal/20344
2 parents df624d2 + 63665ad commit ba4f045

File tree

4 files changed

+28
-6
lines changed

4 files changed

+28
-6
lines changed

docs/reference-manual/native-image/BuildOutput.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Below is the example output when building a native executable of the `HelloWorld
2424
GraalVM Native Image: Generating 'helloworld' (executable)...
2525
================================================================================
2626
[1/8] Initializing... (2.8s @ 0.15GB)
27-
Java version: 20+34, vendor version: GraalVM CE 20-dev+34.1
27+
Java version: 25+13, vendor version: GraalVM CE 25-dev+13.1
2828
Graal compiler: optimization level: 2, target machine: x86-64-v3
2929
C compiler: gcc (linux, x86_64, 12.2.0)
3030
Garbage collector: Serial GC (max heap size: 80% of RAM)
@@ -49,7 +49,7 @@ GraalVM Native Image: Generating 'helloworld' (executable)...
4949
7.03MB (32.02%) for image heap: 93,301 objects and 5 resources
5050
8.96MB (40.83%) for debug info generated in 1.0s
5151
659.13kB ( 2.93%) for other data
52-
21.96MB in total
52+
21.96MB in total image size, 21.04MB in total file size
5353
--------------------------------------------------------------------------------
5454
Top 10 origins of code area: Top 10 object types in image heap:
5555
4.03MB java.base 1.14MB byte[] for code metadata
@@ -201,6 +201,10 @@ The progress indicator is printed periodically at an increasing interval.
201201
### <a name="stage-creating"></a>Creating Image
202202
In this stage, the native binary is created and written to disk.
203203
Debug info is also generated as part of this stage (if requested).
204+
This section breaks down the total image size as well as [code area](#glossary-code-area) and [image heap](#glossary-image-heap) (see below for more details).
205+
The total image size is calculated before linking by summing the sizes of the code area, image heap, debug information (if requested and embedded in the binary), and other data.
206+
The total file size is the actual size of the image on disk after linking.
207+
Typically, the file size is slightly smaller than the image size due to additional link time optimizations.
204208

205209
#### <a name="glossary-code-area"></a>Code Area
206210
The code area contains machine code produced by the Graal compiler for all reachable methods.

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ByteFormattingUtil.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ public class ByteFormattingUtil {
3030
private static final double BYTES_TO_GB = 1000d * 1000d * 1000d;
3131

3232
public static String bytesToHuman(long bytes) {
33+
assert bytes >= 0;
3334
if (bytes < BYTES_TO_KB) {
34-
return toHuman(bytes, "B");
35+
return plainBytes(bytes, "B");
3536
} else if (bytes < BYTES_TO_MB) {
3637
return toHuman(bytes / BYTES_TO_KB, "kB");
3738
} else if (bytes < BYTES_TO_GB) {
@@ -48,4 +49,9 @@ public static String bytesToHumanGB(long bytes) {
4849
private static String toHuman(double value, String unit) {
4950
return "%.2f%s".formatted(value, unit);
5051
}
52+
53+
private static String plainBytes(long value, String unit) {
54+
assert 0 <= value && value < BYTES_TO_KB;
55+
return "%d%s".formatted(value, unit);
56+
}
5157
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,7 @@ protected void doRun(Map<Method, CEntryPointData> entryPoints, JavaMainSupport j
737737
compileQueue.purge();
738738

739739
int numCompilations = codeCache.getOrderedCompilations().size();
740+
int imageDiskFileSize = -1;
740741

741742
try (StopTimer t = TimerCollection.createTimerAndStart(TimerCollection.Registry.WRITE)) {
742743
loader.watchdog.recordActivity();
@@ -758,14 +759,21 @@ protected void doRun(Map<Method, CEntryPointData> entryPoints, JavaMainSupport j
758759

759760
AfterImageWriteAccessImpl afterConfig = new AfterImageWriteAccessImpl(featureHandler, loader, hUniverse, inv, tmpDir, image.getImageKind(), debug);
760761
featureHandler.forEachFeature(feature -> feature.afterImageWrite(afterConfig));
762+
try {
763+
// size changes during linking and afterConfig phase
764+
imageDiskFileSize = (int) inv.getOutputFile().toFile().length();
765+
} catch (Exception e) {
766+
imageDiskFileSize = -1; // we can't read a disk file size
767+
}
761768
}
762769
try (StopTimer t = TimerCollection.createTimerAndStart(TimerCollection.Registry.ARCHIVE_LAYER)) {
763770
if (ImageLayerBuildingSupport.buildingSharedLayer()) {
764771
ImageSingletonsSupportImpl.HostedManagement.persist();
765772
HostedImageLayerBuildingSupport.singleton().archiveLayer(imageName);
766773
}
767774
}
768-
reporter.printCreationEnd(image.getImageFileSize(), heap.getLayerObjectCount(), image.getImageHeapSize(), codeCache.getCodeAreaSize(), numCompilations, image.getDebugInfoSize());
775+
reporter.printCreationEnd(image.getImageFileSize(), heap.getLayerObjectCount(), image.getImageHeapSize(), codeCache.getCodeAreaSize(), numCompilations, image.getDebugInfoSize(),
776+
imageDiskFileSize);
769777
}
770778
}
771779

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ public void setDebugInfoTimer(Timer timer) {
584584
this.debugInfoTimer = timer;
585585
}
586586

587-
public void printCreationEnd(int imageFileSize, int heapObjectCount, long imageHeapSize, int codeAreaSize, int numCompilations, int debugInfoSize) {
587+
public void printCreationEnd(int imageFileSize, int heapObjectCount, long imageHeapSize, int codeAreaSize, int numCompilations, int debugInfoSize, int imageDiskFileSize) {
588588
recordJsonMetric(ImageDetailKey.IMAGE_HEAP_OBJECT_COUNT, heapObjectCount);
589589
Timer imageTimer = getTimer(TimerCollection.Registry.IMAGE);
590590
Timer writeTimer = getTimer(TimerCollection.Registry.WRITE);
@@ -620,7 +620,11 @@ public void printCreationEnd(int imageFileSize, int heapObjectCount, long imageH
620620
recordJsonMetric(ImageDetailKey.NUM_COMP_UNITS, numCompilations);
621621
l().a(format, ByteFormattingUtil.bytesToHuman(otherBytes), Utils.toPercentage(otherBytes, imageFileSize))
622622
.doclink("other data", "#glossary-other-data").println();
623-
l().a("%9s in total", ByteFormattingUtil.bytesToHuman(imageFileSize)).println();
623+
l().a("%9s in total image size", ByteFormattingUtil.bytesToHuman(imageFileSize));
624+
if (imageDiskFileSize >= 0) {
625+
l().a(", %s in total file size", ByteFormattingUtil.bytesToHuman(imageDiskFileSize));
626+
}
627+
l().println();
624628
printBreakdowns();
625629
ImageSingletons.lookup(ProgressReporterFeature.class).afterBreakdowns();
626630
printRecommendations();

0 commit comments

Comments
 (0)