JVM加载

加载:
预加载:当系统被启用时直接加载需要的资源到内存中
懒加载:双重检查锁,通过双重判断进行检查是否需要创建实例,如果实例是null,第二次检查为同步锁->原因:当前实例是null,而在JVM中new和赋值是异步行为

类加载器:
类加载器:通过一个类的全限定名(绝对路径)来获取这个类的二进制字节流
类加载器作用:将编译后的class文件加载到内存中
类加载器分类:
启动类加载器:加载java的基础类,但由于涉及虚拟机本地实现细节(属于虚拟机实现的一部分),所以不允许被直接引用
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
扩展类加载器:加载jre/lib/ext扩展的jar包,可以直接被使用
URL[] urls = ((URLClassLoader) ClassLoader.getSystemClassLoader().getParent()).getURLs();
应用程序类加载器:加载用户的jar包,即编写的class文件
URL[] urls = ((URLClassLoader) ClassLoader.getSystemClassLoader()).getURLs();

加载类型:
全盘负责:当一个加载器加载某个类的时候,这个类的依赖和引用也会被这个加载器加载,除非依赖的已经被其他加载器加载了。例:
A创建B,A被a加载器类加载,那么依赖于A的B也会被a加载器加载。
父类委托:向父加载器委托加载(递归进行),直到无法再被递归,避免一个类被重复加载

加载器的父子关系:
启动类加载器>扩展类加载器>系统类加载器>用户自定义加载器

<think>我们正在讨论JVM如何加载本地字体,特别是关于JAVA_FONTS的机制和配置方法。根据引用[3]和[4],我们知道在Java应用程序中,字体问题可能会导致异常,例如`JRFontNotFoundException`。因此,了解JVM加载字体的机制和如何配置JAVA_FONTS非常重要。 ### JVM字体加载机制 JVM在启动时会加载系统可用的字体。在Java中,字体管理是通过`java.awt.Font`类和相关类实现的。JVM会从以下位置加载字体: 1. **JRE的`lib/fonts`目录**:这是JRE自带的字体目录。 2. **操作系统字体目录**:例如,在Windows上是`C:\Windows\Fonts`,在Linux上是`/usr/share/fonts`等。 3. **用户自定义字体目录**:可以通过设置系统属性或环境变量来指定额外的字体目录。 其中,环境变量`JAVA_FONTS`就是用来指定额外的字体目录的。当设置了`JAVA_FONTS`后,JVM会将该变量指定的目录添加到字体搜索路径中。 ### 配置JAVA_FONTS的方法 要配置`JAVA_FONTS`,你可以在启动JVM之前设置环境变量。具体方法取决于你的操作系统和启动方式。 #### 在Linux/Unix系统中 1. **临时设置**:在终端中执行命令时设置环境变量。 ```bash export JAVA_FONTS=/path/to/your/fonts/directory java -jar your_application.jar ``` 2. **永久设置**:将`export JAVA_FONTS=/path/to/your/fonts/directory`添加到你的shell配置文件(如`~/.bashrc`或`~/.profile`)中,然后执行`source ~/.bashrc`使其生效。 #### 在Windows系统中 1. **临时设置**:在命令提示符中设置。 ```cmd set JAVA_FONTS=C:\path\to\your\fonts\directory java -jar your_application.jar ``` 2. **永久设置**:通过系统属性设置环境变量。 - 右键点击“此电脑” -> “属性” -> “高级系统设置” -> “环境变量” -> 在“系统变量”或“用户变量”中新建变量`JAVA_FONTS`,值为字体目录的路径。 ### 验证字体加载 你可以通过以下Java代码来验证JVM是否成功加载了字体: ```java import java.awt.Font; import java.awt.GraphicsEnvironment; public class ListFonts { public static void main(String[] args) { Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); for (Font font : fonts) { System.out.println(font.getFontName()); } } } ``` 运行这段代码将列出JVM当前可用的所有字体名称。确保你设置的字体目录中的字体出现在列表中。 ### 注意事项 1. 如果字体文件是TrueType(.ttf)或OpenType(.otf)格式,JVM通常能够加载它们。 2. 在Linux系统中,有时需要刷新字体缓存(使用`fc-cache -fv`)才能使新添加的字体生效,但JVM的`JAVA_FONTS`目录通常不需要刷新系统字体缓存,因为JVM会直接读取该目录。 3. 如果使用Docker等容器环境,需要确保容器内存在字体文件,并正确设置`JAVA_FONTS`环境变量。 ### 引用说明 在Java应用程序中,字体问题是一个常见的问题,特别是在生成PDF或图像时。通过正确配置`JAVA_FONTS`,可以避免诸如`Font '宋体' is not available to the JVM`这样的异常[^4]。 §§相关问题§§ 1. JVM在启动时加载字体的具体过程是怎样的? 2. 除了设置JAVA_FONTS,还有哪些方法可以让JVM识别自定义字体? 3. 在容器化环境中如何配置JVM字体?</think>### JVM加载本地JAVA_FONTS的机制与配置方法 #### 一、加载机制 JVM通过以下路径搜索字体文件: 1. **默认字体目录**:`$JAVA_HOME/lib/fonts`(JRE内置字体) 2. **操作系统字体目录**: - Windows:`C:\Windows\Fonts` - Linux:`/usr/share/fonts/` - macOS:`/Library/Fonts/` 3. **JAVA_FONTS环境变量路径**:用户自定义的字体目录[^3][^4] 4. **用户级字体目录**:如Linux的`~/.local/share/fonts/` 加载流程: 1. JVM启动时初始化`sun.font.FontManager` 2. 扫描上述路径的字体文件(.ttf/.ttc/.otf等) 3. 建立字体名到字体文件的映射关系 4. 通过`java.awt.Font`类提供字体服务 #### 二、配置方法 **1. 设置环境变量(推荐)** ```bash # Linux/macOS export JAVA_FONTS=/path/to/custom/fonts java -jar yourapp.jar # Windows set JAVA_FONTS=C:\custom_fonts java -jar yourapp.jar ``` **2. JVM参数配置** ```bash java -Djava.awt.fonts=/path/to/fonts -Dsun.java2d.fontpath=/path/to/fonts ... ``` **3. 程序内加载(代码级)** ```java // 动态注册字体 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("font.ttf"))); ``` #### 三、常见问题解决 **字体缺失异常处理**: 当出现`Font 'xxx' is not available to the JVM`错误时: 1. 确认字体文件已放入`JAVA_FONTS`目录 2. 检查文件权限:`chmod 644 *.ttf`(Linux) 3. 清除字体缓存:删除`~/.java/fonts`目录 4. 验证字体格式:`file font.ttf`(应显示TrueType/OpenType) **容器环境配置**: 在Docker中需确保: ```Dockerfile COPY fonts/ /usr/share/fonts/custom/ ENV JAVA_FONTS=/usr/share/fonts/custom ``` #### 四、验证配置 ```java // 检查可用字体 Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); Arrays.stream(fonts).map(Font::getName).forEach(System.out::println); ``` > **关键点**:JVM优先加载`JAVA_FONTS`路径的字体,该目录应包含完整的字体文件(如simsun.ttf),而非仅字体名[^4]。对于中文环境,宋体/黑体等需显式提供。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值