引用了一个不可用的位置 它可能是一个在本机或网络上u盘显示引用了一个不可用的位置( 二 )


文章插图
什么使内存占用更低:

  • 加载的类没有元数据
工作中仍需要在非堆内存中编译代码 。将动态加载的类的所有元数据保存在Metaspace中会节省很多空间(不需要在Metaspace中执行内存回收过程)
  • 没有用于JIT优化的分析数据,没有解释器代码,没有JIT结构
JVM收集关于应用程序的分析数据,以确定可以应用哪种优化 。这是不必要的,因为我们的字节码已经在本地代码中了 。因此,我们可以丢弃包含分析数据和解释器的整个段代码缓存 。优化后的 *** 以不同的方式存储在二进制文件中 。
形象鲜明,前景光明本节的最后一个注意事项是一个新特性——隔离 。简单地说,Isolates是一种能够将堆划分成更小的独立“堆”的技术 。应该是很有效的,例如在处理请求的情况下 。
如果处理在堆上分配了大量对象,我们可以将请求(实际上是请求运行所在的线程)放入分离的隔离中 。最大的优点是可以非常快速地分配和丢弃隔离,而不需要执行任何GC(都知道的,当线程离开给定的隔离时,所有对象都变成了垃圾,因为这些对象不必从其他隔离对象引用) 。不过这个技术仍然在开发中,可以期待一下 。
原生图像要付出什么代价?本机映像是一种非常好的工具,适用于较小的应用程序,可以帮助我们启动和内存占用 。然而,我们需要为此付出代价,并调整我们的应用程序,使之符合预先编译 。我们可以在SubstrateVM限制中找到一组受支持和不受支持的特性 。我只是简单地指出最痛苦的部分:
  • 不支持JVMTI、Java代理、JMX、JFR
这可能是运行在JVM和本机映像上的应用程序之间的最大差距 。本机映像不支持任何已知的通过JVMTI或JMX连接的分析器,我们需要依靠内核特性来确定我们的应用程序中发生了什么 。通常用于检测类的Java代理也不受支持(通常用于测量执行时间或分配率) 。在这种情况下,即使是Java飞行记录器和Java任务控制系统也是无价的 。
  • 仅对较小的堆有效
由于使用了SerialGC,我们不应该使用更大的堆,这可能会严重影响延迟 。
  • 生成的本机代码效率就那样吧
JIT因为它可以访问应用程序运行时配置文件,并且可以推测和插入陷阱来进行反优化,所以总是更有效 。我们可以通过使用一个可用的基于概要文件的优化特性来减少AOT和JIT之间的差异GraalVM企业版 。
  • 反射模糊
我一点也不喜欢反射,但是很多框架都是基于反射的,它们必须进行调整或者使用额外的配置文件来定义二进制文件中的类和 ***。我可以推荐一个关于SubstrateVM反射的非常详细的页面 。
  • 不支持线程转储和堆转储
喜欢就