通过类名就知道这是一个平台有关的类,通过对该类的学习可以帮助我们实现一个跨平台的应用。但是有些方法放的实现不是很好,比如:isWindows0。通过File的separator就可以判断出来。没必要那么复杂把。 目前平台的判断是推崇能力判断,这里也是通过这样来判断是否是android的,jdk的版本。这种思想最初好像是js来判断浏览器的版本。还有就是PlatformDependent是一个对外的接口,真正的实现为PlatformDependent0类,这是一个代理模式吗

能力判断:

 Class.forName("android.app.Application", false, getSystemClassLoader());

上面是判断平台是否为android.  该方法用来判断该类是否存在,false表示不实例化一个Class对象。

反射作用:

JDK中有很多的类的字段或者方法是私有的,通过反射我们就可以访问这些私有的属性和方法。下面是怎么创建一个UnSafe对象的代码

                Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
unsafe = (Unsafe) unsafeField.get(null);

Unsafe.getUnsafe()不能直接访问

Unsafe的使用

在这个类中大量使用了unsafe的功能

/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you 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 io.netty.util.internal; import io.netty.util.CharsetUtil;
import io.netty.util.internal.chmv8.ConcurrentHashMapV8;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory; import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.regex.Matcher;
import java.util.regex.Pattern; /**
*
* 用来检测运行时系统的属性的工具类,可以通过设置io.netty.noUnsafe属性禁止使用sun.misc.Unsafe对象
* System.setProperty("io.netty.allocator.type","pooled");
* System.setPropperty("io.netty.noUnsafe",false)
* -XX:MaxDirectMemorySize
*
* 该类实现实现:class加载的时候获取系统的属性保存到statuc变量中,然后访问的时候直接返回这个变量
*/
public final class PlatformDependent { private static final InternalLogger logger = InternalLoggerFactory.getInstance(PlatformDependent.class); private static final Pattern MAX_DIRECT_MEMORY_SIZE_ARG_PATTERN = Pattern.compile(
"\\s*-XX:MaxDirectMemorySize\\s*=\\s*([0-9]+)\\s*([kKmMgG]?)\\s*$"); private static final boolean IS_ANDROID = isAndroid0();
private static final boolean IS_WINDOWS = isWindows0();
private static final boolean IS_ROOT = isRoot0(); private static final int JAVA_VERSION = javaVersion0(); /**
* android不支持TCP_NODELAY这个TCP选项
*/
private static final boolean CAN_ENABLE_TCP_NODELAY_BY_DEFAULT = !isAndroid(); private static final boolean HAS_UNSAFE = hasUnsafe0();
private static final boolean CAN_USE_CHM_V8 = HAS_UNSAFE && JAVA_VERSION < 8;
private static final boolean DIRECT_BUFFER_PREFERRED =
HAS_UNSAFE && !SystemPropertyUtil.getBoolean("io.netty.noPreferDirect", false);
private static final long MAX_DIRECT_MEMORY = maxDirectMemory0(); /**
* 字节数组的基本偏移
* arrayBaseOffset方法是一个本地方法,可以获取数组第一个元素的偏移地址
* 数组是个对象,数组存储了数据和一些对象信息
*/
private static final long ARRAY_BASE_OFFSET = arrayBaseOffset0(); private static final boolean HAS_JAVASSIST = hasJavassist0(); private static final File TMPDIR = tmpdir0(); private static final int BIT_MODE = bitMode0(); private static final int ADDRESS_SIZE = addressSize0(); static {
if (logger.isDebugEnabled()) {
logger.debug("-Dio.netty.noPreferDirect: {}", !DIRECT_BUFFER_PREFERRED);
} if (!hasUnsafe() && !isAndroid()) {
logger.info(
"Your platform does not provide complete low-level API for accessing direct buffers reliably. " +
"Unless explicitly requested, heap buffer will always be preferred to avoid potential system " +
"unstability.");
}
} /**
* Returns {@code true} if and only if the current platform is Android
*/
public static boolean isAndroid() {
return IS_ANDROID;
} /**
* Return {@code true} if the JVM is running on Windows
*/
public static boolean isWindows() {
return IS_WINDOWS;
} /**
* Return {@code true} if the current user is root. Note that this method returns
* {@code false} if on Windows.
*/
public static boolean isRoot() {
return IS_ROOT;
} /**
* Return the version of Java under which this library is used.
*/
public static int javaVersion() {
return JAVA_VERSION;
} /**
* Returns {@code true} if and only if it is fine to enable TCP_NODELAY socket option by default.
*/
public static boolean canEnableTcpNoDelayByDefault() {
return CAN_ENABLE_TCP_NODELAY_BY_DEFAULT;
} /**
* 如果classpath下sun.misc.Unsafe可用,那么返回True,用来提高访问direct内存的性能
* @return
*/
public static boolean hasUnsafe() {
return HAS_UNSAFE;
} /**
* Returns {@code true} if the platform has reliable low-level direct buffer access API and a user specified
* {@code -Dio.netty.preferDirect} option.
*
* 如果用户定义了 -Dio.netty.preferDirect的参数同时可以通过api访问direct buffer
*/
public static boolean directBufferPreferred() {
return DIRECT_BUFFER_PREFERRED;
} /**
* Returns the maximum memory reserved for direct buffer allocation.
*/
public static long maxDirectMemory() {
return MAX_DIRECT_MEMORY;
} /**
* Returns {@code true} if and only if Javassist is available.
*/
public static boolean hasJavassist() {
return HAS_JAVASSIST;
} /**
* Returns the temporary directory.
*/
public static File tmpdir() {
return TMPDIR;
} /**
* Returns the bit mode of the current VM (usually 32 or 64.)
*/
public static int bitMode() {
return BIT_MODE;
} /**
* Return the address size of the OS.
* 4 (for 32 bits systems ) and 8 (for 64 bits systems).
*/
public static int addressSize() {
return ADDRESS_SIZE;
} public static long allocateMemory(long size) {
return PlatformDependent0.allocateMemory(size);
} public static void freeMemory(long address) {
PlatformDependent0.freeMemory(address);
} /**
* Raises an exception bypassing compiler checks for checked exceptions.
*/
public static void throwException(Throwable t) {
if (hasUnsafe()) {
PlatformDependent0.throwException(t);
} else {
PlatformDependent.<RuntimeException>throwException0(t);
}
} @SuppressWarnings("unchecked")
private static <E extends Throwable> void throwException0(Throwable t) throws E {
throw (E) t;
} /**
* Creates a new fastest {@link ConcurrentMap} implementaion for the current platform.
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap() {
if (CAN_USE_CHM_V8) {
return new ConcurrentHashMapV8<K, V>();
} else {
return new ConcurrentHashMap<K, V>();
}
} /**
* Creates a new fastest {@link ConcurrentMap} implementaion for the current platform.
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap(int initialCapacity) {
if (CAN_USE_CHM_V8) {
return new ConcurrentHashMapV8<K, V>(initialCapacity);
} else {
return new ConcurrentHashMap<K, V>(initialCapacity);
}
} /**
* Creates a new fastest {@link ConcurrentMap} implementaion for the current platform.
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap(int initialCapacity, float loadFactor) {
if (CAN_USE_CHM_V8) {
return new ConcurrentHashMapV8<K, V>(initialCapacity, loadFactor);
} else {
return new ConcurrentHashMap<K, V>(initialCapacity, loadFactor);
}
} /**
* Creates a new fastest {@link ConcurrentMap} implementaion for the current platform.
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap(
int initialCapacity, float loadFactor, int concurrencyLevel) {
if (CAN_USE_CHM_V8) {
return new ConcurrentHashMapV8<K, V>(initialCapacity, loadFactor, concurrencyLevel);
} else {
return new ConcurrentHashMap<K, V>(initialCapacity, loadFactor, concurrencyLevel);
}
} /**
* Creates a new fastest {@link ConcurrentMap} implementaion for the current platform.
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentHashMap(Map<? extends K, ? extends V> map) {
if (CAN_USE_CHM_V8) {
return new ConcurrentHashMapV8<K, V>(map);
} else {
return new ConcurrentHashMap<K, V>(map);
}
} /**
* Try to deallocate the specified direct {@link ByteBuffer}. Please note this method does nothing if
* the current platform does not support this operation or the specified buffer is not a direct buffer.
*/
public static void freeDirectBuffer(ByteBuffer buffer) {
if (hasUnsafe() && !isAndroid()) {
// only direct to method if we are not running on android.
// See https://github.com/netty/netty/issues/2604
PlatformDependent0.freeDirectBuffer(buffer);
}
} public static long directBufferAddress(ByteBuffer buffer) {
return PlatformDependent0.directBufferAddress(buffer);
} public static Object getObject(Object object, long fieldOffset) {
return PlatformDependent0.getObject(object, fieldOffset);
} public static Object getObjectVolatile(Object object, long fieldOffset) {
return PlatformDependent0.getObjectVolatile(object, fieldOffset);
} public static int getInt(Object object, long fieldOffset) {
return PlatformDependent0.getInt(object, fieldOffset);
} public static long objectFieldOffset(Field field) {
return PlatformDependent0.objectFieldOffset(field);
} public static byte getByte(long address) {
return PlatformDependent0.getByte(address);
} public static short getShort(long address) {
return PlatformDependent0.getShort(address);
} public static int getInt(long address) {
return PlatformDependent0.getInt(address);
} public static long getLong(long address) {
return PlatformDependent0.getLong(address);
} public static void putOrderedObject(Object object, long address, Object value) {
PlatformDependent0.putOrderedObject(object, address, value);
} public static void putByte(long address, byte value) {
PlatformDependent0.putByte(address, value);
} public static void putShort(long address, short value) {
PlatformDependent0.putShort(address, value);
} public static void putInt(long address, int value) {
PlatformDependent0.putInt(address, value);
} public static void putLong(long address, long value) {
PlatformDependent0.putLong(address, value);
} public static void copyMemory(long srcAddr, long dstAddr, long length) {
PlatformDependent0.copyMemory(srcAddr, dstAddr, length);
} public static void copyMemory(byte[] src, int srcIndex, long dstAddr, long length) {
PlatformDependent0.copyMemory(src, ARRAY_BASE_OFFSET + srcIndex, null, dstAddr, length);
} public static void copyMemory(long srcAddr, byte[] dst, int dstIndex, long length) {
PlatformDependent0.copyMemory(null, srcAddr, dst, ARRAY_BASE_OFFSET + dstIndex, length);
} /**
* Create a new optimized {@link AtomicReferenceFieldUpdater} or {@code null} if it
* could not be created. Because of this the caller need to check for {@code null} and if {@code null} is returned
* use {@link AtomicReferenceFieldUpdater#newUpdater(Class, Class, String)} as fallback.
*/
public static <U, W> AtomicReferenceFieldUpdater<U, W> newAtomicReferenceFieldUpdater(
Class<U> tclass, String fieldName) {
if (hasUnsafe()) {
try {
return PlatformDependent0.newAtomicReferenceFieldUpdater(tclass, fieldName);
} catch (Throwable ignore) {
// ignore
}
}
return null;
} /**
* Create a new optimized {@link AtomicIntegerFieldUpdater} or {@code null} if it
* could not be created. Because of this the caller need to check for {@code null} and if {@code null} is returned
* use {@link AtomicIntegerFieldUpdater#newUpdater(Class, String)} as fallback.
*/
public static <T> AtomicIntegerFieldUpdater<T> newAtomicIntegerFieldUpdater(
Class<?> tclass, String fieldName) {
if (hasUnsafe()) {
try {
return PlatformDependent0.newAtomicIntegerFieldUpdater(tclass, fieldName);
} catch (Throwable ignore) {
// ignore
}
}
return null;
} /**
* Create a new optimized {@link AtomicLongFieldUpdater} or {@code null} if it
* could not be created. Because of this the caller need to check for {@code null} and if {@code null} is returned
* use {@link AtomicLongFieldUpdater#newUpdater(Class, String)} as fallback.
*/
public static <T> AtomicLongFieldUpdater<T> newAtomicLongFieldUpdater(
Class<?> tclass, String fieldName) {
if (hasUnsafe()) {
try {
return PlatformDependent0.newAtomicLongFieldUpdater(tclass, fieldName);
} catch (Throwable ignore) {
// ignore
}
}
return null;
} /**
* Create a new {@link Queue} which is safe to use for multiple producers (different threads) and a single
* consumer (one thread!).
*/
public static <T> Queue<T> newMpscQueue() {
return new MpscLinkedQueue<T>();
} /**
* Return the {@link ClassLoader} for the given {@link Class}.
*/
public static ClassLoader getClassLoader(final Class<?> clazz) {
return PlatformDependent0.getClassLoader(clazz);
} /**
* Return the context {@link ClassLoader} for the current {@link Thread}.
*/
public static ClassLoader getContextClassLoader() {
return PlatformDependent0.getContextClassLoader();
} /**
* Return the system {@link ClassLoader}.
*/
public static ClassLoader getSystemClassLoader() {
return PlatformDependent0.getSystemClassLoader();
} private static boolean isAndroid0() {
boolean android;
try {
/**
* 下面只是判断android.app.Application是否存在,而不用实例化class对象
*/
Class.forName("android.app.Application", false, getSystemClassLoader());
android = true;
} catch (Exception e) {
// Failed to load the class uniquely available in Android.
android = false;
} if (android) {
logger.debug("Platform: Android");
}
return android;
} private static boolean isWindows0() {
boolean windows = SystemPropertyUtil.get("os.name", "").toLowerCase(Locale.US).contains("win");
if (windows) {
logger.debug("Platform: Windows");
}
return windows;
} private static boolean isRoot0() {
if (isWindows()) {
return false;
} String[] ID_COMMANDS = { "/usr/bin/id", "/bin/id", "id", "/usr/xpg4/bin/id"};
Pattern UID_PATTERN = Pattern.compile("^(?:0|[1-9][0-9]*)$");
for (String idCmd: ID_COMMANDS) {
Process p = null;
BufferedReader in = null;
String uid = null;
try {
p = Runtime.getRuntime().exec(new String[] { idCmd, "-u" });
in = new BufferedReader(new InputStreamReader(p.getInputStream(), CharsetUtil.US_ASCII));
uid = in.readLine();
in.close(); for (;;) {
try {
int exitCode = p.waitFor();
if (exitCode != 0) {
uid = null;
}
break;
} catch (InterruptedException e) {
// Ignore
}
}
} catch (Exception e) {
// Failed to run the command.
uid = null;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// Ignore
}
}
if (p != null) {
try {
p.destroy();
} catch (Exception e) {
// Android sometimes triggers an ErrnoException.
}
}
} if (uid != null && UID_PATTERN.matcher(uid).matches()) {
logger.debug("UID: {}", uid);
return "0".equals(uid);
}
} logger.debug("Could not determine the current UID using /usr/bin/id; attempting to bind at privileged ports."); Pattern PERMISSION_DENIED = Pattern.compile(".*(?:denied|not.*permitted).*");
for (int i = 1023; i > 0; i --) {
ServerSocket ss = null;
try {
ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(i));
if (logger.isDebugEnabled()) {
logger.debug("UID: 0 (succeded to bind at port {})", i);
}
return true;
} catch (Exception e) {
// Failed to bind.
// Check the error message so that we don't always need to bind 1023 times.
String message = e.getMessage();
if (message == null) {
message = "";
}
message = message.toLowerCase();
if (PERMISSION_DENIED.matcher(message).matches()) {
break;
}
} finally {
if (ss != null) {
try {
ss.close();
} catch (Exception e) {
// Ignore.
}
}
}
} logger.debug("UID: non-root (failed to bind at any privileged ports)");
return false;
} /**
* 通过Class.forName来检测JDK的版本6,7,8
* @return
*/
@SuppressWarnings("LoopStatementThatDoesntLoop")
private static int javaVersion0() {
int javaVersion; // Not really a loop
for (;;) {
// Android
if (isAndroid()) {
javaVersion = 6;
break;
} try {
Class.forName("java.time.Clock", false, getClassLoader(Object.class));
javaVersion = 8;
break;
} catch (Exception e) {
// Ignore
} try {
Class.forName("java.util.concurrent.LinkedTransferQueue", false, getClassLoader(BlockingQueue.class));
javaVersion = 7;
break;
} catch (Exception e) {
// Ignore
} javaVersion = 6;
break;
} if (logger.isDebugEnabled()) {
logger.debug("Java version: {}", javaVersion);
}
return javaVersion;
} /**
* 是否可以使用sun.misc.Unsafe
* @return
*/
private static boolean hasUnsafe0() {
boolean noUnsafe = SystemPropertyUtil.getBoolean("io.netty.noUnsafe", false);
logger.debug("-Dio.netty.noUnsafe: {}", noUnsafe); if (isAndroid()) {
logger.debug("sun.misc.Unsafe: unavailable (Android)");
return false;
} if (noUnsafe) {
logger.debug("sun.misc.Unsafe: unavailable (io.netty.noUnsafe)");
return false;
} // Legacy properties
boolean tryUnsafe;
if (SystemPropertyUtil.contains("io.netty.tryUnsafe")) {
tryUnsafe = SystemPropertyUtil.getBoolean("io.netty.tryUnsafe", true);
} else {
tryUnsafe = SystemPropertyUtil.getBoolean("org.jboss.netty.tryUnsafe", true);
} if (!tryUnsafe) {
logger.debug("sun.misc.Unsafe: unavailable (io.netty.tryUnsafe/org.jboss.netty.tryUnsafe)");
return false;
} try {
boolean hasUnsafe = PlatformDependent0.hasUnsafe();
logger.debug("sun.misc.Unsafe: {}", hasUnsafe ? "available" : "unavailable");
return hasUnsafe;
} catch (Throwable t) {
// Probably failed to initialize PlatformDependent0.
return false;
}
} private static long arrayBaseOffset0() {
if (!hasUnsafe()) {
return -1;
} return PlatformDependent0.arrayBaseOffset();
} /**
* 可用的最大的director memory
* @return
*/
private static long maxDirectMemory0() {
long maxDirectMemory = 0;
try {
// Try to get from sun.misc.VM.maxDirectMemory() which should be most accurate.
Class<?> vmClass = Class.forName("sun.misc.VM", true, getSystemClassLoader());
Method m = vmClass.getDeclaredMethod("maxDirectMemory");
maxDirectMemory = ((Number) m.invoke(null)).longValue();
} catch (Throwable t) {
// Ignore
} if (maxDirectMemory > 0) {
return maxDirectMemory;
} try {
// Now try to get the JVM option (-XX:MaxDirectMemorySize) and parse it.
// Note that we are using reflection because Android doesn't have these classes.
Class<?> mgmtFactoryClass = Class.forName(
"java.lang.management.ManagementFactory", true, getSystemClassLoader());
Class<?> runtimeClass = Class.forName(
"java.lang.management.RuntimeMXBean", true, getSystemClassLoader()); Object runtime = mgmtFactoryClass.getDeclaredMethod("getRuntimeMXBean").invoke(null); @SuppressWarnings("unchecked")
List<String> vmArgs = (List<String>) runtimeClass.getDeclaredMethod("getInputArguments").invoke(runtime);
for (int i = vmArgs.size() - 1; i >= 0; i --) {
Matcher m = MAX_DIRECT_MEMORY_SIZE_ARG_PATTERN.matcher(vmArgs.get(i));
if (!m.matches()) {
continue;
} maxDirectMemory = Long.parseLong(m.group(1));
switch (m.group(2).charAt(0)) {
case 'k': case 'K':
maxDirectMemory *= 1024;
break;
case 'm': case 'M':
maxDirectMemory *= 1024 * 1024;
break;
case 'g': case 'G':
maxDirectMemory *= 1024 * 1024 * 1024;
break;
}
break;
}
} catch (Throwable t) {
// Ignore
} if (maxDirectMemory <= 0) {
maxDirectMemory = Runtime.getRuntime().maxMemory();
logger.debug("maxDirectMemory: {} bytes (maybe)", maxDirectMemory);
} else {
logger.debug("maxDirectMemory: {} bytes", maxDirectMemory);
} return maxDirectMemory;
} /**
* javassist可以动态的生成类
* @return
*/
private static boolean hasJavassist0() {
if (isAndroid()) {
return false;
} boolean noJavassist = SystemPropertyUtil.getBoolean("io.netty.noJavassist", false);
logger.debug("-Dio.netty.noJavassist: {}", noJavassist); if (noJavassist) {
logger.debug("Javassist: unavailable (io.netty.noJavassist)");
return false;
} try {
JavassistTypeParameterMatcherGenerator.generate(Object.class, getClassLoader(PlatformDependent.class));
logger.debug("Javassist: available");
return true;
} catch (Throwable t) {
// Failed to generate a Javassist-based matcher.
logger.debug("Javassist: unavailable");
logger.debug(
"You don't have Javassist in your class path or you don't have enough permission " +
"to load dynamically generated classes. Please check the configuration for better performance.");
return false;
}
} /**
* 通过io.netty.tmpdir 或者 java.io.tmpdir 配置netty的临时目录
* @return
*/
private static File tmpdir0() {
File f;
try {
f = toDirectory(SystemPropertyUtil.get("io.netty.tmpdir"));
if (f != null) {
logger.debug("-Dio.netty.tmpdir: {}", f);
return f;
} f = toDirectory(SystemPropertyUtil.get("java.io.tmpdir"));
if (f != null) {
logger.debug("-Dio.netty.tmpdir: {} (java.io.tmpdir)", f);
return f;
} // This shouldn't happen, but just in case ..
if (isWindows()) {
f = toDirectory(System.getenv("TEMP"));
if (f != null) {
logger.debug("-Dio.netty.tmpdir: {} (%TEMP%)", f);
return f;
} String userprofile = System.getenv("USERPROFILE");
if (userprofile != null) {
f = toDirectory(userprofile + "\\AppData\\Local\\Temp");
if (f != null) {
logger.debug("-Dio.netty.tmpdir: {} (%USERPROFILE%\\AppData\\Local\\Temp)", f);
return f;
} f = toDirectory(userprofile + "\\Local Settings\\Temp");
if (f != null) {
logger.debug("-Dio.netty.tmpdir: {} (%USERPROFILE%\\Local Settings\\Temp)", f);
return f;
}
}
} else {
f = toDirectory(System.getenv("TMPDIR"));
if (f != null) {
logger.debug("-Dio.netty.tmpdir: {} ($TMPDIR)", f);
return f;
}
}
} catch (Exception ignored) {
// Environment variable inaccessible
} // Last resort.
if (isWindows()) {
f = new File("C:\\Windows\\Temp");
} else {
f = new File("/tmp");
} logger.warn("Failed to get the temporary directory; falling back to: {}", f);
return f;
} @SuppressWarnings("ResultOfMethodCallIgnored")
private static File toDirectory(String path) {
if (path == null) {
return null;
} File f = new File(path);
f.mkdirs(); if (!f.isDirectory()) {
return null;
} try {
return f.getAbsoluteFile();
} catch (Exception ignored) {
return f;
}
} /**
* 获取操作系统是多少位的32 或者64
* @return
*/
private static int bitMode0() {
// Check user-specified bit mode first.
int bitMode = SystemPropertyUtil.getInt("io.netty.bitMode", 0);
if (bitMode > 0) {
logger.debug("-Dio.netty.bitMode: {}", bitMode);
return bitMode;
} // And then the vendor specific ones which is probably most reliable.
bitMode = SystemPropertyUtil.getInt("sun.arch.data.model", 0);
if (bitMode > 0) {
logger.debug("-Dio.netty.bitMode: {} (sun.arch.data.model)", bitMode);
return bitMode;
}
bitMode = SystemPropertyUtil.getInt("com.ibm.vm.bitmode", 0);
if (bitMode > 0) {
logger.debug("-Dio.netty.bitMode: {} (com.ibm.vm.bitmode)", bitMode);
return bitMode;
} // os.arch also gives us a good hint.
String arch = SystemPropertyUtil.get("os.arch", "").toLowerCase(Locale.US).trim();
if ("amd64".equals(arch) || "x86_64".equals(arch)) {
bitMode = 64;
} else if ("x86".equals(arch) || "i386".equals(arch) || "i486".equals(arch) || "i586".equals(arch) || "i686".equals(arch)) {
bitMode = 32;
} if (bitMode > 0) {
logger.debug("-Dio.netty.bitMode: {} (os.arch: {})", bitMode, arch);
} // Last resort: guess from VM name and then fall back to most common 64-bit mode.
String vm = SystemPropertyUtil.get("java.vm.name", "").toLowerCase(Locale.US);
Pattern BIT_PATTERN = Pattern.compile("([1-9][0-9]+)-?bit");
Matcher m = BIT_PATTERN.matcher(vm);
if (m.find()) {
return Integer.parseInt(m.group(1));
} else {
return 64;
}
} private static int addressSize0() {
if (!hasUnsafe()) {
return -1;
}
return PlatformDependent0.addressSize();
} private PlatformDependent() {
// only static method supported
}
}

netty中的PlatformDependent的更多相关文章

  1. Netty中ByteBuf的引用计数线程安全的实现原理

    原文链接 Netty中ByteBuf的引用计数线程安全的实现原理 代码仓库地址 ByteBuf 实现了ReferenceCounted 接口,实现了引用计数接口,该接口的retain(int) 方法为 ...

  2. netty中的ByteBuf

    网络数据的基本单位总是字节.Java NIO 提供了 ByteBuffer 作为它 的字节容器,但是这个类使用起来过于复杂,而且也有些繁琐. Netty 的 ByteBuffer 替代品是 ByteB ...

  3. Netty中NioEventLoopGroup的创建源码分析

    NioEventLoopGroup的无参构造: public NioEventLoopGroup() { this(0); } 调用了单参的构造: public NioEventLoopGroup(i ...

  4. Netty中的ChannelFuture和ChannelPromise

    在Netty使用ChannelFuture和ChannelPromise进行异步操作的处理 这是官方给出的ChannelFutur描述 * | Completed successfully | * + ...

  5. Netty中FastThreadLocal源码分析

    Netty中使用FastThreadLocal替代JDK中的ThreadLocal[JAVA]ThreadLocal源码分析,其用法和ThreadLocal 一样,只不过从名字FastThreadLo ...

  6. Netty 中的消息解析和编解码器

    本篇内容主要梳理一下 Netty 中编解码器的逻辑和编解码器在 Netty 整个链路中的位置. 前面我们在分析 ChannelPipeline 的时候说到入站和出站事件的处理都在 pipeline 中 ...

  7. Netty 中的内存分配浅析-数据容器

    本篇接续前一篇继续讲 Netty 中的内存分配.上一篇 先简单做一下回顾: Netty 为了更高效的管理内存,自己实现了一套内存管理的逻辑,借鉴 jemalloc 的思想实现了一套池化内存管理的思路: ...

  8. 深度揭秘Netty中的FastThreadLocal为什么比ThreadLocal效率更高?

    阅读这篇文章之前,建议先阅读和这篇文章关联的内容. 1. 详细剖析分布式微服务架构下网络通信的底层实现原理(图解) 2. (年薪60W的技巧)工作了5年,你真的理解Netty以及为什么要用吗?(深度干 ...

  9. 聊聊 Netty 那些事儿之 Reactor 在 Netty 中的实现(创建篇)

    本系列Netty源码解析文章基于 4.1.56.Final版本 在上篇文章<聊聊Netty那些事儿之从内核角度看IO模型>中我们花了大量的篇幅来从内核角度详细讲述了五种IO模型的演进过程以 ...

随机推荐

  1. HihoCoder1445 重复旋律5(后缀自动机)

    重复旋律5 时间限制:10000ms 单点时限:2000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi想知道一部作品 ...

  2. 2017-2018-1 20179215《Linux内核原理与分析》第十周作业

    第17章 设备与模块 一.设备类型  除了以上3种典型的设备之外,其实Linux中还有一些其他的设备类型,其中见的较多的应该算是"伪设备".所谓"伪设备",其实 ...

  3. 排列(加了点小set就过了,哈哈哈)

    Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数. 输入描述: 1 2 3 4 1 1 2 3 0 1 2 3 0 0 0 0输出 ...

  4. hadoop-hbase学习笔记

    create "t",{NAME=>"t_id"},{NAME=>"t_vl"} describe "t" ...

  5. vertex shader must minimally write all four components of POSITION

    Though the POSITION semantic must be written out by the vertex shader, it cannot be read in by the p ...

  6. Installing Redis more properly

    Installing Redis more properly Running Redis from the command line is fine just to hack a bit with i ...

  7. Nagios 里面监控MySQL事务一直RUNNING没有结束的报警Shell脚本 (转)

    序言:        业务报警订单提交异常,页面一直没有反应,排查后是事务没有提交或者回滚导致,想到如果及时监控事务的运行状态报警出来,那么就可以及时排查出问题所在,方便运营处理,所以自己就弄了一个s ...

  8. HUD2102(基础bfs)

    A计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  9. 关于Java中集合的讲解~

    http://blog.csdn.net/zccst/article/details/5092816 comparable& Comparator 都是用来实现集合中的排序的,只是Compar ...

  10. Even uploading a JPG file can lead to Cross-Site Content Hijacking (client-side attack)!

    Introduction: This post is going to introduce a new technique that has not been covered previously i ...