目的本文讨论JDK8及以后的堆和栈内存管理的基本概念。以及GC及其算法的基础知识。内存管理的重要性Java垃圾收集器不能保证堆内存完全空闲,开发者也不可能强制垃圾收集器在特定时间运行。因此,了解Java中内存管理的工作原理对于开发程序非常有帮助。了解内存管理有助于编写优化的内存高效代码,并有助于避免程序中出现任何与内存相关的问题,这些问题可能会导致应用程序运行缓慢,并有助于避免StackOverFlowError和OutOfMemoryError等错误。Stackmemory栈是一种线性数据结构,Java分配的静态内存,用来存放堆对象引用,同时也存放Java原始类型值。堆栈以后进先出(LIFO)的顺序访问内存,并且比堆内存更快。每个线程在内存中创建自己的堆栈,这反过来使堆栈内存线程安全。Java中的方法只能在方法体内(在方法范围内)访问堆栈内存中的对象。当一个方法完成执行时,该方法对应的块将从堆栈中清除。在上面的程序中,我们可以看到当控制到达main方法时,栈中会有一个args的入口。然后当控件在下一行时,一个新的条目被添加到堆栈中。当控件超出方法的范围时,引用将从堆栈中删除。如果堆栈内存已满,JVM将抛出StackOverFlowError。堆内存JVM使用堆在运行时为Java对象动态分配内存。任何新对象都存储在堆上,对对象(实例变量)的引用存储在堆栈上。您可以在下面的示例中看到示例代码的变量是如何存储在堆和堆栈上的。下面是上面代码片段在堆中的内存分配。堆内存可以分解成更小的部分,称为代,分别是年轻代、老年代/永久代和永久代。新生代中的所有新对象都分配在这个内存段中。新生代由Eden和两个Survivor空间组成。当Eden填满时,垃圾回收发生在年轻代上,称为MinorGC。在MinorGC期间,来自年轻代的引用对象被移动到Survivor空间#1,并且对象的年龄增加。例如,在下图中,“Object1”和“Object2”在第一次MinorGC后将被移动到Survivorspace#1,并且它们将具有指定的年龄。如果“对象1”在第一次MinorGC中幸存下来,则年龄为零。现在如果“object1”在下一次MinorGC中也存活下来,那么它会被移动到survivorspace2,age会再次增加。在第二次MinorGC期间,驻留在Survivor空间#1中的对象(带有引用)将被移动到Survivor#2并且年龄将增加(即根据示例,年龄将从零变为一)。并且将删除整个年轻代空间中所有未引用的对象。老年代老年代是存放长寿命对象(最老的对象)的地方。新生代对象有一个上限或阈值年龄。一旦一个对象达到了这个上限,这个对象就会被移动到老一代或老年代。tenuredgeneration的这部分堆内存用于存储运行时类和方法的元数据。从JDK8开始,这部分内存已经被Java彻底去掉,取而代之的是Metaspace概念。您仍然可以设置--XX:PermSize和-XX:MaxPermSize配置。但是,如果您在JDK8或更高版本上运行您的应用程序,您将在运行时收到警告。从JDK8开始引入的元空间是从本机内存分配的可调整大小的内存区域。元空间保存类元数据,它不是连续的内存位置。每当元空间达到为元空间分配的最大大小时,Java就会触发自动GC以释放元空间内存。Metaspace选项是-XX:MetaspaceSize=size和-XX:MaxMetaspaceSize=size垃圾收集Java程序被编译并转换为字节码并在JVM(Java虚拟机)上运行。Java程序的对象是在程序的私有堆内存上创建的。随着时间的推移,创建了更多的对象,并且程序不再需要某些对象(未引用和取消作用域)。垃圾收集是Java执行自动内存管理并通过删除未引用的对象来释放内存空间的过程。JVM结合了不同的垃圾收集算法。垃圾回收算法检查内存中的每个引用对象,其余对象被视为垃圾回收。GC算法的类型以下是JVM可用的4种GC算法。ParallelGCSerialGCConcurrentMarkandScanG1Garbage-first并行GC专为具有中等到大量数据的多线程应用程序而设计,在多处理器环境中运行良好。但它会在垃圾收集期间冻结所有应用程序线程。JVM选项是-XX:+UseParallelGC,您可以选择使用-XX:ParallelGCThreads=设置并行线程数。串行GC主要是为单线程环境设计的。LiekParallelGC,它还在垃圾收集期间冻结所有应用程序线程。JVM选项是-XX:+UseSerialGC。ConcurrentMarkandSink(CMS)这是一种并发GC,旨在减少GC暂停时间,并且不需要停止正在运行的应用程序来执行GC。这就是此过程比串行或并行GC慢的原因。它使用多线程进行垃圾收集,并且可以与垃圾收集器共享处理器资源。JVM选项是-XX:+UseConcMarkSweepGC。G1垃圾收集器(G1GC)这是另一种最高效的并发GC,专为具有大量内存的多处理器环境而设计。JVM选项是-XX:+UseG1GC。选择GC算法的参数除非你对GC时间有特殊要求,需要额外规范,否则最好让JVM自己选择GC算法。如果要选择和配置GC算法,需要考虑的参数很少,例如堆大小、CPU内核数、应用程序数据集容量、吞吐量、暂停时间、延迟。A。堆大小——分配给JVM的内存总量。更大的堆大小意味着GC将花费更多时间。较大的堆意味着JVM不会像较小的堆那样频繁地触发GC。JVM选项是-Xms=和-Xmx=,??其中-Xms是最小值,-Xmx是最大值。b.CPU内核-GC算法因CPU内核的数量而异。其中一些是为单核CPU设计的,一些是为多核CPU设计的。C。应用程序数据集——这是指应用程序使用的对象数量。创建的新对象数量较多,导致年轻代空间被填满,需要更多的GC时间来释放内存。d.吞吐量-它是完成应用程序任务所需的总时间(GC之外)的百分比。它与分配给JVM的内存成反比。e.暂停时间——GC算法在内存回收过程中停止应用程序所花费的时间。它根据不同的GC算法而有所不同。JVM选项是-XX:MaxGCPauseMillis=f,Latency-它是应用程序的响应时间,直接取决于GC暂停时间。基于以上参数,您必须选择最适合您的应用程序的GC算法。例如:串行GC,如果应用程序很小并且使用较小的数据集并且在没有暂停时间要求的单个处理器上运行。如果应用程序性能是最高优先级,则并行GC。·当应用程序的响应时间很重要时,G1GC或CMS因为它不会在运行GC时保留应用程序。原文链接:https://dzone.com/articles/jvm-memory-architecture-and-gc
