美文网首页
Java虚拟机以及垃圾回收总结

Java虚拟机以及垃圾回收总结

作者: nzdxwl | 来源:发表于2019-11-01 19:56 被阅读0次

Java虚拟机主要由三大部分组成:类加载器、运行时数据区和执行引擎

运行时数据区:由方法区、、Java虚拟机栈、本地方法栈和程序计数器组成。
运行时常量池数据:保存在方法区中。
执行引擎:由即时编译器(JIT Compiler)和垃圾收集器组成。

方法区空间为所有Java虚拟机线程共享,存放编译后的代码:

The method area is analogous to the storage area for compiled code of a conventional language or analogous to the "text" segment in an operating system process. It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods used in class and instance initialization and interface initialization.

垃圾回收

使用C语言开发时,需要开发者手动分配和回收内存,在Java中则是通过垃圾收集器自动处理。

在早期一段时间,JVM是通过标记和整理所有对象来进行垃圾回收,不仅效率低下且对象列表的逐步增长会导致垃圾回收时间越来越长。后来通过研究发现,应用程序中大部分对象的存活期都是较短的,前期会有大部分对象存活,但随着时间的推移会越来越少。通过对这种现象的发现和研究,对堆进行分代的划分:分为年轻代,老年代和永久代

JDK1.7堆结构

JDK1.7 Java Hotspot 堆结构
JDK1.8默认的堆结构
JDK1.8 Java Hotspot 默认堆结构

年轻代又由一个eden区和两个survivor区构成,首先新对象会分配在eden区,当eden区分配满时会触发轻量级垃圾回收(minor garbage collection),将eden区中存活的对象移动到第一个survivor区(S0),并且清空eden区,随后继续分配新对象到eden区;当再次触发垃圾回收时,则会将eden区和S0中存活的对象移动到另一个survivor区(S1),然后清空eden区和S0,你可以将两个survivor区看成临时交换区,其中一个始终保持为空。存活的对象每经历一次垃圾回收可以看成增长一岁,当增长足够岁数后会移到老年代。[1]

当老年代分配满时,则会触发重大级别的垃圾回收(Major garbage collection),Major GC会需要更长的时间,因为它对整个堆进行垃圾回收,涉及所有存活的对象。无论是Minor还是Major GC都是会导致应用暂停的事件(Stop the World Event): 应用的所有线程都会挂起直到垃圾回收结束。所以对于需要即时响的应用程序,要尽可能减少Major GC事件的发生。

System.gc() 和 Runtime.getRuntime().gc() 方法在JDK1.6 Hotspot JVM的实现是暂停应用程序所有线程并对整个堆进行垃圾回收的,所以不要一般情况下不要在代码中调用这两个方法,交由JVM自己进行垃圾回收,如有调用了,可以设置并发收集: -XX:+ExplicitGCInvokesConcurrent[2]

永久代则是JVM存放描述所需类和方法的元数据的区间,另外Java 类库中的类和方法也是存放在这里。在JDK1.8中,PermGen即永久代已经被移除了。[3]

在官方Java虚拟机调优文档[4]最后,有提到:

    Java classes have an internal representation within Java Hotspot VM and are referred to as class metadata. In previous releases of Java Hotspot VM, the class metadata was allocated in the so called permanent generation. In JDK 8, the permanent generation was removed and the class metadata is allocated in native memory. The amount of native memory that can be used for class metadata is by default unlimited. Use the option MaxMetaspaceSize to put an upper limit on the amount of native memory used for class metadata.
    Java Hotspot VM explicitly manages the space used for metadata. Space is requested from the OS and then divided into chunks. A class loader allocates space for metadata from its chunks (a chunk is bound to a specific class loader). When classes are unloaded for a class loader, its chunks are recycled for reuse or returned to the OS. Metadata uses space allocated by mmap, not by malloc.


垃圾收集器

串行收集器

如果应用程序只有很少的数据集时,可以使用串行收集器:-XX:+UseSerialGC

并行收集器

使用并行收集器时的堆结构
在server VM虚拟机上面,并行收集器是默认的垃圾回收器。 可以使用 -XX:+UseParallelGC 来启用,另外可以使用-XX:-UseParallelOldGC来关闭并行压缩功能。
使用并行收集器时,你可以指定垃圾回收的最大中断时间、吞吐量以及寻址空间;
指定最大中断时间: 默认是没有最大中断时间的限制的,可以通过参数-XX:MaxGCPauseMillis=<N>设定,然后JVM会调整垃圾回收的相关设定,比如堆大小等参数来使得垃圾回收中断时间小于设定的值,这个最大中断时间只是设定一个目标,不是一定能够达成。
吞吐量: 吞吐量则是应用正常运行时间和垃圾回收时间的比例,可通过 参数-XX:GCTimeRatio=<N>来设定,比如设置 -XX:GCTimeRatio=19说明有5%的时间是用来垃圾回收的, -XX:GCTimeRatio=99则表示只允许1%的时间用着垃圾回收上,这个参数的默认值是99.
内存空间:可以通过 -Xmx<N>来指定最大堆空间,另外,并行收集器还有个隐含的目标,就是在能达成以上两个目标的情况下最小化堆空间。
由于并行收集器需要调整堆分代空间,这就是使用它时堆结构与默认不同的原因了。

并发标记清理收集器(CMS: Concurrent Mark Sweep)

使用参数 -XX:+UseConcMarkSweepGC来设置使用CMS收集器,
CMS收集器可以在应用程序线程执行的同时,并发使用多个线程来追踪存活的对象以及进行内存整理。

垃圾优先收集器(G1: Garbage-First)

G1垃圾收集器的堆结构
使用参数 -XX:+UseG1GC来启用G1垃圾收集器,它的设计意图是满足更小GC中断时间的需求,将堆内存平均分割为固定大小的区间,是逻辑意义上面的分代,用不同空区间集合表示不同代,另外占用超过一半区间的对象被视为极大对象,会放置在多个区间合并起来的空间。

JVM配置[5]

查看当前JVM配置:
java -XX:+PrintCommandLineFlags -version

常用参数:

-Xmnsize or -XX: NewSize·: 设置年轻代大小, 示例: -Xmn512m
jdk 1.7: Sets the size of the young generation (nursery).
jdk 1.8: Sets the initial and maximum size (in bytes) of the heap for the young generation (nursery). Append the letter k or K to indicate kilobytes, m or M to indicate megabytes, g or G to indicate gigabytes.

-Xmssize: 设置堆初始大小,示例:-Xms1g
Sets the initial size (in bytes) of the heap. This value must be a multiple of 1024 and greater than 1 MB. Append the letter k or K to indicate kilobytes, m or M to indicate megabytes, g or G to indicate gigabytes.

-Xmxsize: 设置可分配内存池最大值
Specifies the maximum size (in bytes) of the memory allocation pool in bytes. This value must be a multiple of 1024 and greater than 2 MB. For server deployments, -Xms and -Xmx are often set to the same value.

-Xsssize: 设置线程栈大小
Sets the thread stack size (in bytes). Append the letter k or K to indicate KB, m or M to indicate MB, g or G to indicate GB. The default value depends on virtual memory.

-XX:+PrintCommandLineFlags
Enables printing of ergonomically selected JVM flags that appeared on the command line. It can be useful to know the ergonomic values set by the JVM, such as the heap space size and the selected garbage collector. By default, this option is disabled and flags are not printed.

-XX:InitialHeapSize=size

-XX:InitialSurvivorRatio=ratio

Hotspot JVM常见问题:

Frequently Asked Questions About the Java HotSpot VM


  1. 配置对象最大可经历所少次垃圾回收才移到老年代的参数 -XX:MaxTenuringThreshold,这个参数的最大值是15,对于并行收集器,该参数默认值是最大值15,对于CMS收集器,该参数值默认值是6.

  2. Concurrent Mark Sweep Collector Enhancements

  3. JEP 122: Remove the Permanent Generation

  4. JVM Garbage Collection Tuning Guide

  5. JDK1.8 JVM参数配置项

相关文章

  • 深入Java虚拟机之 -- 总结面试篇

    系列文章: 深入Java虚拟机之 -- 总结面试篇深入Java虚拟机之 --- JVM的爱恨情仇JAVA 垃圾回收...

  • Java垃圾回收

    本文主要摘自《深入理解Java虚拟机》,内容较多,尽量全面概括了 Java 垃圾回收机制、垃圾回收器以及内存分配策...

  • 浅析JAVA的垃圾回收机制(GC)

    1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供...

  • JVM垃圾回收算法

    Java基础:JVM垃圾回收算法 [toc] 参考:Java基础:JVM垃圾回收算法图解JVM垃圾回收算法 总结:...

  • Java虚拟机以及垃圾回收总结

    Java虚拟机主要由三大部分组成:类加载器、运行时数据区和执行引擎 运行时数据区:由方法区、堆、Java虚拟机栈、...

  • Java垃圾回收

    1.什么是垃圾回收?垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供的一种...

  • Spark性能优化之Java虚拟机垃圾回收调优

    一、Java虚拟机垃圾回收调优的背景 如果在持久化RDD的时候,持久化了大量数据,那么Java虚拟机的垃圾回收就可...

  • 每日一问:讲讲 Java 虚拟机的类加载机制

    前面给大家讲解了 Java 虚拟的内存结构 以及 Java 虚拟机的垃圾回收机制,我们更加明白了 Java 的内...

  • Java垃圾回收小结

    垃圾回收是Java最大的特点之一,由于垃圾回收是java虚拟机自动进行,在代码开发中不用去管理垃圾什么时候回收。而...

  • java中内存的那点事情

    概念 虚拟机垃圾回收 谈到内存一定少不了java虚拟机的垃圾回收策略,java语言不再像C/C++那样需要人工手动...

网友评论

      本文标题:Java虚拟机以及垃圾回收总结

      本文链接:https://www.haomeiwen.com/subject/vintbctx.html