Loading services/core/java/com/android/server/am/MemoryStatUtil.java +0 −24 Original line number Diff line number Diff line Loading @@ -63,8 +63,6 @@ public final class MemoryStatUtil { private static final Pattern CACHE_IN_BYTES = Pattern.compile("total_cache (\\d+)"); private static final Pattern SWAP_IN_BYTES = Pattern.compile("total_swap (\\d+)"); private static final Pattern RSS_HIGH_WATERMARK_IN_KILOBYTES = Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB"); private static final Pattern PROCFS_RSS_IN_KILOBYTES = Pattern.compile("VmRSS:\\s*(\\d+)\\s*kB"); private static final Pattern PROCFS_ANON_RSS_IN_KILOBYTES = Loading Loading @@ -112,15 +110,6 @@ public final class MemoryStatUtil { return parseMemoryStatFromProcfs(readFileContents(statPath), readFileContents(statusPath)); } /** * Reads RSS high-water mark of a process from procfs. Returns value of the VmHWM field in * /proc/PID/status in kilobytes or 0 if not available. */ public static int readRssHighWaterMarkFromProcfs(int pid) { final String statusPath = String.format(Locale.US, PROC_STATUS_FILE_FMT, pid); return parseVmHWMFromProcfs(readFileContents(statusPath)); } /** * Reads cmdline of a process from procfs. * Loading Loading @@ -203,19 +192,6 @@ public final class MemoryStatUtil { } } /** * Parses RSS high-water mark out from the contents of the /proc/pid/status file in procfs. The * returned value is in kilobytes. */ @VisibleForTesting static int parseVmHWMFromProcfs(String procStatusContents) { if (procStatusContents == null || procStatusContents.isEmpty()) { return 0; } return (int) tryParseLong(RSS_HIGH_WATERMARK_IN_KILOBYTES, procStatusContents); } /** * Parses cmdline out of the contents of the /proc/pid/cmdline file in procfs. * Loading services/core/java/com/android/server/stats/ProcfsMemoryUtil.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.stats; import android.os.FileUtils; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import java.io.File; import java.io.IOException; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; final class ProcfsMemoryUtil { private static final String TAG = "ProcfsMemoryUtil"; /** Path to procfs status file: /proc/pid/status. */ private static final String STATUS_FILE_FMT = "/proc/%d/status"; private static final Pattern RSS_HIGH_WATER_MARK_IN_KILOBYTES = Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB"); private ProcfsMemoryUtil() {} /** * Reads RSS high-water mark of a process from procfs. Returns value of the VmHWM field in * /proc/PID/status in kilobytes or 0 if not available. */ static int readRssHighWaterMarkFromProcfs(int pid) { final String statusPath = String.format(Locale.US, STATUS_FILE_FMT, pid); return parseVmHWMFromStatus(readFile(statusPath)); } /** * Parses RSS high-water mark out from the contents of the /proc/pid/status file in procfs. The * returned value is in kilobytes. */ @VisibleForTesting static int parseVmHWMFromStatus(String contents) { if (contents.isEmpty()) { return 0; } final Matcher matcher = RSS_HIGH_WATER_MARK_IN_KILOBYTES.matcher(contents); try { return matcher.find() ? Integer.parseInt(matcher.group(1)) : 0; } catch (NumberFormatException e) { Slog.e(TAG, "Failed to parse value", e); return 0; } } private static String readFile(String path) { try { final File file = new File(path); return FileUtils.readTextFile(file, 0 /* max */, null /* ellipsis */); } catch (IOException e) { return ""; } } } services/core/java/com/android/server/stats/StatsCompanionService.java +1 −1 Original line number Diff line number Diff line Loading @@ -27,9 +27,9 @@ import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs; import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs; import static com.android.server.stats.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs; import static com.android.server.stats.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs; import static com.android.server.stats.ProcfsMemoryUtil.readRssHighWaterMarkFromProcfs; import android.annotation.NonNull; import android.annotation.Nullable; Loading services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java +0 −13 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import static com.android.server.am.MemoryStatUtil.MemoryStat; import static com.android.server.am.MemoryStatUtil.parseCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs; import static com.android.server.am.MemoryStatUtil.parseVmHWMFromProcfs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; Loading Loading @@ -229,18 +228,6 @@ public class MemoryStatUtilTest { assertNull(parseMemoryStatFromProcfs(contents, PROC_STATUS_CONTENTS)); } @Test public void testParseVmHWMFromProcfs_parsesCorrectValue() { assertEquals(137668, parseVmHWMFromProcfs(PROC_STATUS_CONTENTS)); } @Test public void testParseVmHWMFromProcfs_emptyContents() { assertEquals(0, parseVmHWMFromProcfs("")); assertEquals(0, parseVmHWMFromProcfs(null)); } @Test public void testParseCmdlineFromProcfs_invalidValue() { byte[] nothing = new byte[] {0x00, 0x74, 0x65, 0x73, 0x74}; // \0test Loading services/tests/servicestests/src/com/android/server/stats/ProcfsMemoryUtilTest.java 0 → 100644 +93 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.stats; import static com.android.server.stats.ProcfsMemoryUtil.parseVmHWMFromStatus; import static com.google.common.truth.Truth.assertThat; import androidx.test.filters.SmallTest; import org.junit.Test; /** * Build/Install/Run: * atest FrameworksServicesTests:ProcfsMemoryUtilTest */ @SmallTest public class ProcfsMemoryUtilTest { private static final String STATUS_CONTENTS = "Name:\tandroid.youtube\n" + "State:\tS (sleeping)\n" + "Tgid:\t12088\n" + "Pid:\t12088\n" + "PPid:\t723\n" + "TracerPid:\t0\n" + "Uid:\t10083\t10083\t10083\t10083\n" + "Gid:\t10083\t10083\t10083\t10083\n" + "Ngid:\t0\n" + "FDSize:\t128\n" + "Groups:\t3003 9997 20083 50083 \n" + "VmPeak:\t 4546844 kB\n" + "VmSize:\t 4542636 kB\n" + "VmLck:\t 0 kB\n" + "VmPin:\t 0 kB\n" + "VmHWM:\t 137668 kB\n" // RSS high-water mark + "VmRSS:\t 126776 kB\n" // RSS + "RssAnon:\t 37860 kB\n" + "RssFile:\t 88764 kB\n" + "RssShmem:\t 152 kB\n" + "VmData:\t 4125112 kB\n" + "VmStk:\t 8192 kB\n" + "VmExe:\t 24 kB\n" + "VmLib:\t 102432 kB\n" + "VmPTE:\t 1300 kB\n" + "VmPMD:\t 36 kB\n" + "VmSwap:\t 22 kB\n" // Swap + "Threads:\t95\n" + "SigQ:\t0/13641\n" + "SigPnd:\t0000000000000000\n" + "ShdPnd:\t0000000000000000\n" + "SigBlk:\t0000000000001204\n" + "SigIgn:\t0000000000000001\n" + "SigCgt:\t00000006400084f8\n" + "CapInh:\t0000000000000000\n" + "CapPrm:\t0000000000000000\n" + "CapEff:\t0000000000000000\n" + "CapBnd:\t0000000000000000\n" + "CapAmb:\t0000000000000000\n" + "Seccomp:\t2\n" + "Cpus_allowed:\tff\n" + "Cpus_allowed_list:\t0-7\n" + "Mems_allowed:\t1\n" + "Mems_allowed_list:\t0\n" + "voluntary_ctxt_switches:\t903\n" + "nonvoluntary_ctxt_switches:\t104\n"; @Test public void testParseVmHWMFromStatus_parsesCorrectValue() { assertThat(parseVmHWMFromStatus(STATUS_CONTENTS)).isEqualTo(137668); } @Test public void testParseVmHWMFromStatus_invalidValue() { assertThat(parseVmHWMFromStatus("test\nVmHWM: x0x0x\ntest")).isEqualTo(0); } @Test public void testParseVmHWMFromStatus_emptyContents() { assertThat(parseVmHWMFromStatus("")).isEqualTo(0); } } Loading
services/core/java/com/android/server/am/MemoryStatUtil.java +0 −24 Original line number Diff line number Diff line Loading @@ -63,8 +63,6 @@ public final class MemoryStatUtil { private static final Pattern CACHE_IN_BYTES = Pattern.compile("total_cache (\\d+)"); private static final Pattern SWAP_IN_BYTES = Pattern.compile("total_swap (\\d+)"); private static final Pattern RSS_HIGH_WATERMARK_IN_KILOBYTES = Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB"); private static final Pattern PROCFS_RSS_IN_KILOBYTES = Pattern.compile("VmRSS:\\s*(\\d+)\\s*kB"); private static final Pattern PROCFS_ANON_RSS_IN_KILOBYTES = Loading Loading @@ -112,15 +110,6 @@ public final class MemoryStatUtil { return parseMemoryStatFromProcfs(readFileContents(statPath), readFileContents(statusPath)); } /** * Reads RSS high-water mark of a process from procfs. Returns value of the VmHWM field in * /proc/PID/status in kilobytes or 0 if not available. */ public static int readRssHighWaterMarkFromProcfs(int pid) { final String statusPath = String.format(Locale.US, PROC_STATUS_FILE_FMT, pid); return parseVmHWMFromProcfs(readFileContents(statusPath)); } /** * Reads cmdline of a process from procfs. * Loading Loading @@ -203,19 +192,6 @@ public final class MemoryStatUtil { } } /** * Parses RSS high-water mark out from the contents of the /proc/pid/status file in procfs. The * returned value is in kilobytes. */ @VisibleForTesting static int parseVmHWMFromProcfs(String procStatusContents) { if (procStatusContents == null || procStatusContents.isEmpty()) { return 0; } return (int) tryParseLong(RSS_HIGH_WATERMARK_IN_KILOBYTES, procStatusContents); } /** * Parses cmdline out of the contents of the /proc/pid/cmdline file in procfs. * Loading
services/core/java/com/android/server/stats/ProcfsMemoryUtil.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.stats; import android.os.FileUtils; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import java.io.File; import java.io.IOException; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; final class ProcfsMemoryUtil { private static final String TAG = "ProcfsMemoryUtil"; /** Path to procfs status file: /proc/pid/status. */ private static final String STATUS_FILE_FMT = "/proc/%d/status"; private static final Pattern RSS_HIGH_WATER_MARK_IN_KILOBYTES = Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB"); private ProcfsMemoryUtil() {} /** * Reads RSS high-water mark of a process from procfs. Returns value of the VmHWM field in * /proc/PID/status in kilobytes or 0 if not available. */ static int readRssHighWaterMarkFromProcfs(int pid) { final String statusPath = String.format(Locale.US, STATUS_FILE_FMT, pid); return parseVmHWMFromStatus(readFile(statusPath)); } /** * Parses RSS high-water mark out from the contents of the /proc/pid/status file in procfs. The * returned value is in kilobytes. */ @VisibleForTesting static int parseVmHWMFromStatus(String contents) { if (contents.isEmpty()) { return 0; } final Matcher matcher = RSS_HIGH_WATER_MARK_IN_KILOBYTES.matcher(contents); try { return matcher.find() ? Integer.parseInt(matcher.group(1)) : 0; } catch (NumberFormatException e) { Slog.e(TAG, "Failed to parse value", e); return 0; } } private static String readFile(String path) { try { final File file = new File(path); return FileUtils.readTextFile(file, 0 /* max */, null /* ellipsis */); } catch (IOException e) { return ""; } } }
services/core/java/com/android/server/stats/StatsCompanionService.java +1 −1 Original line number Diff line number Diff line Loading @@ -27,9 +27,9 @@ import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs; import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs; import static com.android.server.stats.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs; import static com.android.server.stats.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs; import static com.android.server.stats.ProcfsMemoryUtil.readRssHighWaterMarkFromProcfs; import android.annotation.NonNull; import android.annotation.Nullable; Loading
services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java +0 −13 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import static com.android.server.am.MemoryStatUtil.MemoryStat; import static com.android.server.am.MemoryStatUtil.parseCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs; import static com.android.server.am.MemoryStatUtil.parseVmHWMFromProcfs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; Loading Loading @@ -229,18 +228,6 @@ public class MemoryStatUtilTest { assertNull(parseMemoryStatFromProcfs(contents, PROC_STATUS_CONTENTS)); } @Test public void testParseVmHWMFromProcfs_parsesCorrectValue() { assertEquals(137668, parseVmHWMFromProcfs(PROC_STATUS_CONTENTS)); } @Test public void testParseVmHWMFromProcfs_emptyContents() { assertEquals(0, parseVmHWMFromProcfs("")); assertEquals(0, parseVmHWMFromProcfs(null)); } @Test public void testParseCmdlineFromProcfs_invalidValue() { byte[] nothing = new byte[] {0x00, 0x74, 0x65, 0x73, 0x74}; // \0test Loading
services/tests/servicestests/src/com/android/server/stats/ProcfsMemoryUtilTest.java 0 → 100644 +93 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.stats; import static com.android.server.stats.ProcfsMemoryUtil.parseVmHWMFromStatus; import static com.google.common.truth.Truth.assertThat; import androidx.test.filters.SmallTest; import org.junit.Test; /** * Build/Install/Run: * atest FrameworksServicesTests:ProcfsMemoryUtilTest */ @SmallTest public class ProcfsMemoryUtilTest { private static final String STATUS_CONTENTS = "Name:\tandroid.youtube\n" + "State:\tS (sleeping)\n" + "Tgid:\t12088\n" + "Pid:\t12088\n" + "PPid:\t723\n" + "TracerPid:\t0\n" + "Uid:\t10083\t10083\t10083\t10083\n" + "Gid:\t10083\t10083\t10083\t10083\n" + "Ngid:\t0\n" + "FDSize:\t128\n" + "Groups:\t3003 9997 20083 50083 \n" + "VmPeak:\t 4546844 kB\n" + "VmSize:\t 4542636 kB\n" + "VmLck:\t 0 kB\n" + "VmPin:\t 0 kB\n" + "VmHWM:\t 137668 kB\n" // RSS high-water mark + "VmRSS:\t 126776 kB\n" // RSS + "RssAnon:\t 37860 kB\n" + "RssFile:\t 88764 kB\n" + "RssShmem:\t 152 kB\n" + "VmData:\t 4125112 kB\n" + "VmStk:\t 8192 kB\n" + "VmExe:\t 24 kB\n" + "VmLib:\t 102432 kB\n" + "VmPTE:\t 1300 kB\n" + "VmPMD:\t 36 kB\n" + "VmSwap:\t 22 kB\n" // Swap + "Threads:\t95\n" + "SigQ:\t0/13641\n" + "SigPnd:\t0000000000000000\n" + "ShdPnd:\t0000000000000000\n" + "SigBlk:\t0000000000001204\n" + "SigIgn:\t0000000000000001\n" + "SigCgt:\t00000006400084f8\n" + "CapInh:\t0000000000000000\n" + "CapPrm:\t0000000000000000\n" + "CapEff:\t0000000000000000\n" + "CapBnd:\t0000000000000000\n" + "CapAmb:\t0000000000000000\n" + "Seccomp:\t2\n" + "Cpus_allowed:\tff\n" + "Cpus_allowed_list:\t0-7\n" + "Mems_allowed:\t1\n" + "Mems_allowed_list:\t0\n" + "voluntary_ctxt_switches:\t903\n" + "nonvoluntary_ctxt_switches:\t104\n"; @Test public void testParseVmHWMFromStatus_parsesCorrectValue() { assertThat(parseVmHWMFromStatus(STATUS_CONTENTS)).isEqualTo(137668); } @Test public void testParseVmHWMFromStatus_invalidValue() { assertThat(parseVmHWMFromStatus("test\nVmHWM: x0x0x\ntest")).isEqualTo(0); } @Test public void testParseVmHWMFromStatus_emptyContents() { assertThat(parseVmHWMFromStatus("")).isEqualTo(0); } }