4年前 (2020-09-12)  爪哇岛 |   抢沙发  387 
文章评分 0 次,平均分 0.0

弱引用软引用虚引用

JVMjava虚拟机中影响垃圾收集GC的有哪些因素?

一些应用程序通过使用终结和弱、软或虚引用与垃圾回收进行交互。

这些特性可以在Java编程语言级别创建性能组件。

例如,依赖终结来关闭文件描述符,这使得外部资源(描述符)依赖于垃圾收集的及时性。依赖垃圾回收来管理内存以外的资源几乎总是一个坏主意。

显式垃圾回收

应用程序可以与垃圾回收交互的另一种方式是通过调用垃圾回收(). 这可能会在不必要时强制执行主要收集(例如,当次要收集就足够了),因此通常应避免。显式垃圾回收的性能影响可以通过使用标志

-XX:+DisableExplicitGC 来衡量,这会导致VM忽略对垃圾回收System.gc()

显式垃圾收集最常见的用法之一是远程方法调用(RMI)的分布式垃圾收集(DGC)。使用RMI的应用程序引用其他虚拟机中的对象。如果不偶尔调用本地堆的垃圾收集,就无法在这些分布式应用程序中收集垃圾,因此RMI会定期强制进行完全回收。可以使用属性控制这些集合的频率,如下例所示:

java -Dsun.rmi.dgc.client.gcInterval=3600000
    -Dsun.rmi.dgc.server.gcInterval=3600000

此示例指定每小时一次的显式垃圾回收,而不是默认的每分钟一次的垃圾回收率。但是,这也可能导致某些对象需要更长的时间才能被回收。这些属性可以设置为高达Long.MAX_值如果不希望DGC活动的时效性有一个上限,那么显式收集之间的时间实际上是无限的。

软引用soft reference

软引用在服务器虚拟机中的存活时间比在客户端中长。

清除速率可以通过命令行选项-XX:SoftRefLRUPolicyMSPerMB=<N>控制,该选项指定堆中每兆字节可用空间的软引用将保持活动(一旦不再是强可访问的)毫秒数(毫秒)。

默认值为每兆字节1000毫秒,这意味着软引用将在堆中每兆字节的可用空间中生存1秒(在收集了对对象的最后一个强引用之后)。这是一个近似的数字,因为软引用仅在垃圾回收期间清除,垃圾回收可能偶尔发生。

类元数据class metaspace

Java类在javahotspotsvm中有一个内部表示,称为类元数据。在javahotspotsvm的早期版本中,类元数据是在所谓的永久生成中分配的。生成的元数据被删除,并且JDK在本地类中被分配了永久内存。默认情况下,可用于类元数据的本机内存量是不受限制的。使用选项MaxMetaspaceSize为类元数据使用的本机内存量设置上限。

javahotspotsvm显式地管理用于元数据的空间。从操作系统请求空间,然后将其分成块。类装入器从它的块中为元数据分配空间(块绑定到特定的类装入器)。当为类装入器卸载类时,它的块被回收以供重用或返回给操作系统。元数据使用由mmap而不是malloc分配的空间。

如果UseCompressedOops处于启用状态,并且使用了UseCompressedClassesPointers,则会将两个逻辑上不同的本机内存区域用于类元数据。UseCompressedClassPointers使用32位偏移量来表示64位进程中的类指针,就像UseCompressedOops用于Java对象引用一样。为这些压缩类指针(32位偏移量)分配一个区域。区域的大小可以用CompressedClassSpaceSize设置,默认为1GB。压缩类指针的空间保留为mmap在初始化时分配的空间,并根据需要提交。MaxMetaspaceSize应用于提交的压缩类空间和其他类元数据的空间之和。

在卸载相应的Java类时释放类元数据。Java类是垃圾收集的结果,为了卸载类和释放类元数据,可能会引入垃圾收集。当为类元数据提交的空间达到某个级别(高水位线)时,将引发垃圾回收。垃圾收集之后,根据从类元数据中释放的空间量,可以提高或降低高水位线。高水位线将提高,以免过早地引发另一次垃圾收集。高水位线最初设置为命令行选项MetaspaceSize的值。根据选项MaxMetaspaceFreeRatio和MinMetaspaceFreeRatio来升高或降低。如果类元数据可用的提交空间占类元数据提交空间总数的百分比大于MaxMetaspaceFreeRatio,则高水位线将降低。如果它小于MinMetaspaceFreeRatio,则高水位线将升高。

堆打印输出示例:

Heap
  PSYoungGen      total 10752K, used 4419K
    [0xffffffff6ac00000, 0xffffffff6b800000, 0xffffffff6b800000)
    eden space 9216K, 47% used
      [0xffffffff6ac00000,0xffffffff6b050d68,0xffffffff6b500000)
    from space 1536K, 0% used
      [0xffffffff6b680000,0xffffffff6b680000,0xffffffff6b800000)
    to   space 1536K, 0% used
      [0xffffffff6b500000,0xffffffff6b500000,0xffffffff6b680000)
  ParOldGen       total 20480K, used 20011K
      [0xffffffff69800000, 0xffffffff6ac00000, 0xffffffff6ac00000)
    object space 20480K, 97% used 
      [0xffffffff69800000,0xffffffff6ab8add8,0xffffffff6ac00000)
  Metaspace       used 2425K, capacity 4498K, committed 4864K, reserved 1056768K
    class space   used 262K, capacity 386K, committed 512K, reserved 1048576K

在以Metaspace开头的行中,used值是用于加载类的空间量。capacity值是当前分配的块中可用于元数据的空间。committed值是可用于块的空间量。保留值是为元数据保留(但不一定要提交)的空间量。以类空间行开头的行包含压缩类指针的元数据的相应值。

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/388.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册