JVM —— 移除永久代

转载来源:https://blog.youkuaiyun.com/wenniuwuren/article/details/51170275

最近准备生产环境 JDK 升级到 1.8,本地先升级了下,发现 -XX:PermSize 和 -XX:MaxPermSize 已经失效,取而代之的是一个新的区域 —— Metaspace(元数据区)。

在 JDK 1.7 及以往的 JDK 版本中,Java 类信息、常量池、静态变量都存储在 Perm(永久代)里。类的元数据和静态变量在类加载的时候分配到 Perm,当类被卸载的时候垃圾收集器从 Perm 处理掉类的元数据和静态变量。当然常量池的东西也会在 Perm 垃圾收集的时候进行处理。

JDK 1.8 的对 JVM 架构的改造将类元数据放到本地内存中,另外,将常量池和静态变量放到 Java 堆里。HotSopt VM 将会为类的元数据明确分配和释放本地内存。在这种架构下,类元信息就突破了原来 -XX:MaxPermSize 的限制,现在可以使用更多的本地内存。这样就从一定程度上解决了原来在运行时生成大量类的造成经常 Full GC 问题,如运行时使用反射、代理等。

分配本地内存发给类元数据在一个称为「块」的数据结构上,不同类元数据将会用不同大小的块存放。每个块与一个类加载器相关联,并且所有被这个类加载器加载的类元数据在这个块下分配的空间存储元数据。不同的应用块的大小将会不同,块大小的分配将会被内部碎片和外部碎片所限制。当类加载器不再使用,所有和这个类加载器相关联的块空间将会被释放。

如果服务器内存足够,升级到 JDK 1.8 修改 JVM 参数最简单的办法就是将 -XX:PermSize 和 -XX:MaxPermSize 参数替换为 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize,因为现在里面只存元数据信息了,给它个大的空间肯定没问题。不过堆得空间因为现在要多存储原来在永久代的常量池和静态变量可能需要稍微扩大些。具体可以根据 GC 日志,和 $JAVA/bin 下的工具做一些权衡和调优


参考及引用:
                   http://openjdk.java.net/jeps/122
                   http://bugs.java.com/view_bug.do?bug_id=6962931
--------------------- 
作者:wenniuwuren 
来源:优快云 
原文:https://blog.youkuaiyun.com/wenniuwuren/article/details/51170275 
版权声明:本文为博主原创文章,转载请附上博文链接!

### JVM底层原理详解 #### 1. JVM内存结构 JVM的内存结构主要包括以下几个部分:堆、方法区(元空间)、栈、本地方法栈和程序计数器。其中,堆是所有线程共享的一块内存区域,用于存储实例化对象和数组[^1]。 #### 2. 执行引擎的发展历程 早期的JVM依赖于解释型编译器来执行Java字节码,这种方式虽然减少了初始编译时间,但由于逐行解释的特点,导致整体执行效率较低。为了提升性能,现JVM引入了热点探测技术和即时编译器(Just-In-Time, JIT)。通过记录码段的执行频率,识别出热点码并将其提前编译为高效的机器码,从而显著提高运行速度[^2]。 #### 3. 方法区的作用与特性 方法区作为JVM的一部分,主要用于存储已被虚拟机加载的类信息、常量以及静态变量等内容。这一区域由所有的线程共同使用,并且其大小可以根据应用需求动态调整。值得注意的是,“永久”的概念在较新的JDK版本中已经被替换成了“元空间”,后者直接利用操作系统级别的内存管理方式来进行扩展[^3]。 #### 4. 垃圾回收机制中的引用类型 除了传统的强引用之外,Java还提供了其他三种类型的引用——软引用(Soft Reference)、弱引用(Weak Reference) 和 虚引用(Phantom Reference),它们各自具有不同的存活周期及用途。特别是弱引用,在GC发生时无论是否有足够的可用空间都会被清理掉;而虚引用则几乎不影响目标对象的生命轨迹,通常配合引用队列一起用来跟踪某个特定时刻之前是否已经发生了回收动作[^4]。 #### 5. 并发处理下的任务调度策略 在线程池的设计当中,当提交一个新的工作任务给ThreadPoolExecutor实例之后,系统会先判断当前活动线程数目是否小于corePoolSize。若是,则创建新线程去执行此任务;如果不是并且workQueue未满的话,则把该任务放入等待队列之中暂存起来直到有空闲资源为止。另外remove方法可用于移除指定的任务项,成功与否取决于实际操作的结果反馈[^5]。 ```java // 示例码展示如何自定义一个简单的线程工厂 public class CustomThreadFactory implements ThreadFactory { private final String threadNamePrefix; public CustomThreadFactory(String prefix){ this.threadNamePrefix = prefix+"-"; } @Override public Thread newThread(Runnable r) { return new Thread(r,this.threadNamePrefix+System.nanoTime()); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值