Reduce the memory usage of the ProtoLogToFile
The protolog in wm/am is generally less than 1kb after being writtem to ProtoOutputStream,
but 'new ProtoOutputStream()' will at least create a byte array of 8kb each time.
This will cause each log to occupy at least 7kb of useless memory.
When the log cached by 'ProtoLogToFile' reaches BUFFER_CAPACITY(1MB), it will occupy 70MB of memory.
This has a greater impact on some low-memory devices.
Bug: 271179026
Bug: 262244460
Merged-In: I368278df6f801b2b2b67974089d4a7f4147d91cc
Change-Id: I368278df6f801b2b2b67974089d4a7f4147d91cc
diff --git a/core/java/com/android/internal/protolog/BaseProtoLogImpl.java b/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
index 4d1234f..ac9188a 100644
--- a/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
@@ -72,11 +72,13 @@
private static final String TAG = "ProtoLog";
private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
static final String PROTOLOG_VERSION = "1.0.0";
+ private static final int DEFAULT_PER_CHUNK_SIZE = 0;
private final File mLogFile;
private final String mViewerConfigFilename;
private final TraceBuffer mBuffer;
protected final ProtoLogViewerConfigReader mViewerConfig;
+ private final int mPerChunkSize;
private boolean mProtoLogEnabled;
private boolean mProtoLogEnabledLockFree;
@@ -156,7 +158,7 @@
return;
}
try {
- ProtoOutputStream os = new ProtoOutputStream();
+ ProtoOutputStream os = new ProtoOutputStream(mPerChunkSize);
long token = os.start(LOG);
os.write(MESSAGE_HASH, messageHash);
os.write(ELAPSED_REALTIME_NANOS, SystemClock.elapsedRealtimeNanos());
@@ -215,10 +217,16 @@
public BaseProtoLogImpl(File file, String viewerConfigFilename, int bufferCapacity,
ProtoLogViewerConfigReader viewerConfig) {
+ this(file, viewerConfigFilename, bufferCapacity, viewerConfig, DEFAULT_PER_CHUNK_SIZE);
+ }
+
+ public BaseProtoLogImpl(File file, String viewerConfigFilename, int bufferCapacity,
+ ProtoLogViewerConfigReader viewerConfig, int perChunkSize) {
mLogFile = file;
mBuffer = new TraceBuffer(bufferCapacity);
mViewerConfigFilename = viewerConfigFilename;
mViewerConfig = viewerConfig;
+ mPerChunkSize = perChunkSize;
}
/**
@@ -364,7 +372,7 @@
try {
long offset =
(System.currentTimeMillis() - (SystemClock.elapsedRealtimeNanos() / 1000000));
- ProtoOutputStream proto = new ProtoOutputStream();
+ ProtoOutputStream proto = new ProtoOutputStream(mPerChunkSize);
proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
proto.write(VERSION, PROTOLOG_VERSION);
proto.write(REAL_TIME_TO_ELAPSED_TIME_OFFSET_MILLIS, offset);
diff --git a/core/java/com/android/internal/protolog/ProtoLogImpl.java b/core/java/com/android/internal/protolog/ProtoLogImpl.java
index 353c6c0..527cfdd 100644
--- a/core/java/com/android/internal/protolog/ProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogImpl.java
@@ -30,6 +30,7 @@
private static final int BUFFER_CAPACITY = 1024 * 1024;
private static final String LOG_FILENAME = "/data/misc/wmtrace/wm_log.winscope";
private static final String VIEWER_CONFIG_FILENAME = "/system/etc/protolog.conf.json.gz";
+ private static final int PER_CHUNK_SIZE = 1024;
private static ProtoLogImpl sServiceInstance = null;
@@ -94,7 +95,10 @@
public static synchronized ProtoLogImpl getSingleInstance() {
if (sServiceInstance == null) {
sServiceInstance = new ProtoLogImpl(
- new File(LOG_FILENAME), BUFFER_CAPACITY, new ProtoLogViewerConfigReader());
+ new File(LOG_FILENAME)
+ , BUFFER_CAPACITY
+ , new ProtoLogViewerConfigReader()
+ , PER_CHUNK_SIZE);
}
return sServiceInstance;
}
@@ -105,8 +109,8 @@
}
public ProtoLogImpl(File logFile, int bufferCapacity,
- ProtoLogViewerConfigReader viewConfigReader) {
- super(logFile, VIEWER_CONFIG_FILENAME, bufferCapacity, viewConfigReader);
- }
+ ProtoLogViewerConfigReader viewConfigReader, int perChunkSize) {
+ super(logFile, VIEWER_CONFIG_FILENAME, bufferCapacity, viewConfigReader, perChunkSize);
+ }
}
diff --git a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
index 3db0116..fdd9194 100644
--- a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
@@ -86,7 +86,7 @@
mFile = testContext.getFileStreamPath("tracing_test.dat");
//noinspection ResultOfMethodCallIgnored
mFile.delete();
- mProtoLog = new ProtoLogImpl(mFile, 1024 * 1024, mReader);
+ mProtoLog = new ProtoLogImpl(mFile, 1024 * 1024, mReader, 1024);
}
@After