一:
虚拟机使用元空间替代了永久代是因为永久代在过去的实现中存在一些问题和限制,而元空间提供了更好的性能和灵活性。以下是一些详细的原因:
内存管理:永久代的内存管理是由虚拟机自身控制的,无法根据应用程序的需求进行动态调整。而元空间使用本地内存进行管理,可以根据应用程序的需求动态分配和释放内存,提高内存的利用率。
永久代内存溢出:在永久代中,存储类的元数据、常量池、静态变量等,当应用程序加载大量类或者使用大量字符串常量时,可能导致永久代内存溢出。而元空间不再有固定的大小限制,可以根据应用程序的需要自动扩展。
类的卸载:在永久代中,由于类的卸载机制比较复杂,很难实现完全的类卸载。而元空间使用本地内存,可以更容易地实现类的卸载,减少内存的占用。
性能优化:元空间的实现采用了更高效的数据结构和算法,例如使用指针碰撞(Bump the Pointer)的方式分配内存,减少内存碎片化,提高内存分配的效率。此外,元空间还支持并发的类加载和卸载操作,提高了性能。
总的来说,元空间相对于永久代来说具有更好的内存管理、更高的性能和更灵活的特性,能够更好地满足现代应用程序的需求。因此,虚拟机选择使用元空间替代永久代
二:
与永久代相比,使用元空间使用方法区具有以下优点:
- 突破内存限制,减少OOM。 由于元空间使用的是本地内存,而不是 JVM 内存,因此理论上,其大小只受限于操作系统的实际可用内存。这大大减少了内存溢出的可能性。相较于永久代在 JVM 堆中预分配的有限空间,元空间的引入提供了更大的空间来存储类元数据。
- 提高 Full GC 的效率。 在永久代中,Full GC 的触发比较频繁,而且效率较低。因为永久代中存放了很多 JVM 需要的类信息,这些数据大多数是不会被清理的,所以 Full GC 往往无法回收多少空间。但在元空间模型中,由于字符串常量池已移至堆中,静态变量也移至 Java 堆或者本地内存,因此可以更有效地进行垃圾回收,避免了因频繁的 Full GC 导致的性能影响。
- 满足不同的类加载需求和动态类加载的情况。 在一些大型的、模块化的应用中,可能需要加载大量的类,这就需要大量的元数据存储空间。元空间可以动态地调整大小,能更好地满足这种需求。
- 避免永久代调优和大小设置的复杂性。 在 Java8 之前的版本中,通常需要手动设置永久代的大小,以避免内存溢出的错误。这增加了应用的配置和管理的复杂性。而元空间使用本地内存,根据实际需求动态调整,大大简化了内存管理的复杂性。