从此

Java 高级编程、I/O File、硬件OSHI、日志/Logger

综合/最新

Java编程专题Nginx Jetty HTTP C/SJakarta EEAndroid应用开发JDK源码Gradle构建Spring
原则 - 首选内存用量小的Quarkus(GraalVM),次选嵌入式Jetty、Open Liberty InstantOn、Open Liberty非快速启动版。

通用


IO File

方案:
  背压式双缓冲队列 - 将“不稳定的网络流”转化为“稳定和缓存较小的内存块”,同时避免了全量载入内存,比单缓冲的 BufferedInputStream 多一份。

尾参指初始容量,会扩充至 ReadLimit - new BufferedInputStream(stream, 64 * 1024).mark(_ReadLimit);

通用

静态方法里获取所在类:
  MethodHandles.lookup().lookupClass();
  带行号所在方法 - StackWalker.getInstance().walk(Stream::findFirst).get() // pkg.App.main(App.java:67)
    或 new Throwable().getStackTrace()[0];

日志:
    static final LazyConstant<System.Logger> LOGGER = LazyConstant.of(() -> {
        var logger = System.getLogger("global"); // Logger.getGlobal()
        var loggerImpl = LogManager.getLogManager().getLogger("global");
        loggerImpl.setLevel(Level.ALL);

        // [可选]控制台输出
        var ch = new ConsoleHandler();
        ch.setLevel(Level.ALL);
        loggerImpl.addHandler(ch);

        try {
            var fh = new FileHandler("global.log");
            fh.setLevel(Level.ALL);
            fh.setFormatter(new SimpleFormatter()); // 默认 XML。
            loggerImpl.addHandler(fh);
        } catch (IOException e) {
            e.printStackTrace(System.err);
        }
        return logger;
    }); //用处 LOGGER.get().log(System.Logger.Level.ALL, "msg..."); LOGGER.get().log(Logger.Level.ALL, MethodHandles.lookup().toString(), ex);

    if (logger.isLoggable(Logger.Level.INFO)) {
      logger.log(Logger.Level.INFO, "Msg: {0}", Arrays.toString(args));
    }
    logger.log(Logger.Level.INFO, () -> "Msg: " + Arrays.toString(args)); // 日志级别不匹配则不执行 Lambda,特别是复杂日志内容。

JDK/JRE

JRE 自定义镜像:
    cd "C:\Program Files\Java\jdk-24\bin"
    ./jlink --help  只含 java.base 则生成后约 30-47MiB。
    [可选] 查看依赖的modules: jdeps HelloWorld.class

    不含应用: ./jlink --output $HOME/Desktop/my-jre/ --add-modules java.base
        ./jlink --output $HOME/Desktop/my-jre/ --add-modules java.base,jdk.localedata --include-locales en,zh-Hans-CN --strip-debug --compress=zip-9
        说明 - 不指定 --module-path 则默认取 JDK 目录 jmods/;可指定 jar(不指定模块名则取文件名) 和通过 jar 或 *.class 生成的 jmod 文件。
          其中 --strip-debug --compress=zip-9 参数均为可选,但建议加上,压缩似乎只针对 my-jre/lib/modules 文件。
    包含应用: ./jlink --output $HOME/Desktop/my-jre/ --module-path ../jmods/:path/to/your-modular.jar:your-modular.jmod --add-modules java.base
        说明 - 运行命令 java --module your.modular/HelloWorld.class

    其他参数:如果想重用参数,可通过配置文件指定 ./jlink @my.conf
        --add-modules java.base,javafx.base,javafx.graphics,javafx.controls --launcher start=java.base/java
        指定本地化语言(默认en_US) ./jlink --add-modules java.base,jdk.localedata --include-locales en,ja,zh-Hans-CN

    清理输出目录: rm -r $HOME/Desktop/my-jre/
    [可选] 创建jmod文件: jmod create --class-path mods/com.example.mymodule --output mymods/com.example.mymodule.jmod --module-version 1.0.0 --main-class com.example.mymodule.MyClass --resource-path resources

其他

OSHI 库获取"设备 ID"(重装会变) - RegistryUtil.getStringValue(WinReg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\SQMClient", "MachineID");
  主板 SMBIOS(DMTF格式/硬件固化): new SystemInfo().getHardware().getComputerSystem().getHardwareUUID();