View Javadoc
1   /*
2    * Copyright 2026 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in
6    * compliance with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13   * implied. See the License for the specific language governing
14   * permissions and limitations under the License.
15   */
16  package io.netty.util.internal;
17  
18  import java.lang.management.ManagementFactory;
19  import java.util.List;
20  
21  /**
22   * Avoid class verification failures on Android.
23   * Android does not have {@link ManagementFactory},
24   * so loading this class on Android will fail with
25   * {@link NoClassDefFoundError}.
26   */
27  final class RuntimeJvmArgs {
28  
29      private static final String MAX_DIRECT_MEMORY_SIZE_ARG =
30              "-XX:MaxDirectMemorySize=";
31  
32      private RuntimeJvmArgs() {
33      }
34  
35      static long parseMaxDirectMemorySize(final long maxDirectMemory) {
36          try {
37              List<String> vmArgs = ManagementFactory
38                      .getRuntimeMXBean()
39                      .getInputArguments();
40              for (int i = vmArgs.size() - 1; i >= 0; i--) {
41                  String arg = vmArgs.get(i);
42                  if (!arg.startsWith(MAX_DIRECT_MEMORY_SIZE_ARG)) {
43                      continue;
44                  }
45                  return parseSize(arg, MAX_DIRECT_MEMORY_SIZE_ARG.length());
46              }
47          } catch (Throwable ignored) {
48              // Ignore
49          }
50          return maxDirectMemory;
51      }
52  
53      static long parseSize(final String arg, final int offset) {
54          String val = arg.substring(offset).trim();
55          if (val.isEmpty()) {
56              return -1;
57          }
58          char lastChar = val.charAt(val.length() - 1);
59          long multiplier;
60          switch (lastChar) {
61              case 'k':
62              case 'K':
63                  multiplier = 1024;
64                  break;
65              case 'm':
66              case 'M':
67                  multiplier = 1024 * 1024;
68                  break;
69              case 'g':
70              case 'G':
71                  multiplier = 1024L * 1024 * 1024;
72                  break;
73              default:
74                  return Long.parseLong(val);
75          }
76          String numStr = val.substring(0, val.length() - 1);
77          return Long.parseLong(numStr) * multiplier;
78      }
79  }