Java内存架构(Java内存模型)

上面是堆的Java内存模型以及Java虚拟机(JVM)中运行的任何Java应用程序的PermGen。 还提供了比率,以使您更好地了解如何在每种世代类型之间分配允许的内存。 以上所有内容完全适用于Java 1.7版(含)。 上面也称为内存模型的“管理区域”。

除上述内容外,还有一个堆栈区域,可以使用-Xss选项进行配置。 该区域保存堆上的引用,本机引用,pc寄存器,代码缓存和所有线程的局部变量。 这也称为内存模型的“本地区域”。

Java内存模型的受管区域(Java内存体系结构)

[年轻一代/苗圃]伊甸园空间

所有新对象都首先在Eden Space中创建。 一旦达到由JVM确定的任意阈值,就会启动次要垃圾回收(Minor GC)。它首先删除所有非引用对象,并将引用对象从“ eden”和“ from”移到“ to”幸存者空间。 GC结束后,将交换“从”和“到”角色(名称)。

[年轻一代/苗圃]幸存者1(来自)

这是幸存者空间的一部分(您可能认为这是幸存者空间中的角色 )。 这是上一个垃圾回收(GC)期间的“ to”角色。

[年轻一代/苗圃] Suvrivor 2(至)

这也是幸存者空间的一部分(您可能认为这也是幸存者空间中的角色 )。 在这里,在GC期间,所有引用的对象
从'from'和'eden'移到。

[上一代]终身任职

根据阈值限制,可以使用-XX:+ PrintTenuringDistribution来检查阈值限制,该限制按年龄显示对象(以字节为单位的空间)–对象从“到” 幸存者空间移动到Tenured空间。 “年龄”是指它在幸存者空间内移动的次数。 还有其他重要的标志,例如-XX:InitialTenuringThreshold,-XX:MaxTenuringThreshold-XX:TargetSurvivorRatio ,它们可以优化使用权和幸存者空间。 通过设置-XX:InitialTenuringThreshold-XX:MaxTenuringThreshold,我们允许'Age'的初始值和最大值,同时保持-XX:+ NeverTenure-XX指定的'Survivor(To)'中的百分比利用率。 + AlwaysTenure,正如他们建议的那样,要么永不保管对象(使用风险较大 ),相反的用法是始终保有权,即始终使用“老一代”。 这里发生的垃圾收集是主要垃圾收集(主要GC)。 通常在堆已满或旧代已满时触发。 这通常是接管执行垃圾回收的“ 世界停止 ”事件或线程。 还有另一种称为完全垃圾收集(Full GC)的GC,它涉及其他内存区域,例如permgen空间。

与整个堆相关的其他重要且有趣的标志是-XX:SurvivorRatio-XX:NewRatio ,它们指定eden空间与幸存者空间的比率以及旧一代与新一代的比率。

[永久世代] Permgen空间

“ Permgen”用于存储以下信息:常量池(内存池),字段和方法数据以及代码。 它们每个都与名称所暗示的特征相同。

垃圾收集算法

串行GC(-XX:UseSerialGC):年轻一代和老一代的GC

为年轻和终身使用的一代使用简单的标记扫描紧凑循环。 这对于客户端系统以及内存占用量少和cpu较小的系统来说非常有用

并行GC(-XX:UseParallelGC):年轻一代和老一代的GC

这使用了N个线程,可以使用-XX:ParallelGCThreads = N进行配置,这里N也是CPU内核的数量。 用于垃圾收集。 它在Young代中将这N个线程用于GC,而在Old代中仅使用一个线程。

并行旧GC(-XX:UseParallelOldGC):年轻一代和老一代的GC

这与Parallel GC相同,不同之处在于它在旧一代和年轻一代中均使用N个线程进行GC。

并发标记和扫描GC(-XX:ConcMarkSweepGC):旧Generaton上的GC

顾名思义,CMS GC将GC所需的停顿最小化。 创建高响应性的应用程序最有用,并且仅在旧一代中才执行GC。 它为GC创建了多个线程,这些线程与应用程序线程并发工作,可以使用-XX:ParallelCMSThreads = n指定这些线程

G1 GC(-XX:UseG1GC):年轻一代和老年人一代的GC(通过将堆分成相等大小的区域)

这是一个并行,并发且递增压缩的低暂停垃圾收集器。 它是在Java 7中引入的,其最终目标是取代CMS GC。 它将堆划分为多个大小相等的区域,然后执行GC,通常从实时数据较少的区域开始-因此,即“垃圾优先”。

最常见的内存不足问题

所有Java开发人员都应该知道的最常见的内存不足问题,以便正确地开始调试,如下所示:

  • 线程“ main”中的异常:java.lang.OutOfMemoryError:Java堆空间这并不一定意味着内存泄漏,这可能是由于为堆配置的空间较小所致。 否则,在寿命长的应用程序中,可能是由于无意中提到了对堆对象的引用(内存泄漏)。 甚至应用程序调用的API都可能包含对不必要的对象的引用。 同样,在过度使用终结器的应用程序中,有时对象会排队到终结队列中。 当这样的应用程序创建更高优先级的线程并导致finalizaton队列中的对象越来越多时,它可能导致内存不足。
  • 线程“ main”中的异常:java.lang.OutOfMemoryError:PermGen空间如果加载了许多类和方法,或者创建了很多字符串文字,尤其是通过使用intern()(从JDK 7开始,不再使用实习字符串) (PermGen的一部分)–则发生这种类型的错误。 发生此类错误时,文本ClassLoader.defineClass可能会出现在所打印的堆栈跟踪顶部附近。
  • 线程“ main”中的异常:java.lang.OutOfMemoryError:请求的数组大小超出VM限制当请求的数组大小大于可用堆大小时,再次发生这种情况。 如果为数组大小请求一个非常大的值,通常可能由于运行时的程序错误而发生。
  • 线程“ main”中的异常:java.lang.OutOfMemoryError:请求<r>的<s>个字节。 交换空间不足?
    通常这可能是内存泄漏的根本原因。 当操作系统没有足够的交换空间另一个进程占用系统上所有可用的内存资源时,就会发生这种情况。 简而言之,由于空间耗尽,它无法从堆中提供请求空间。 该消息指示失败的请求的大小“ s”(以字节为单位)以及内存请求的原因“ r”。 在大多数情况下,消息的<r>部分是报告分配失败的源模块的名称,尽管在某些情况下它表示原因。
  • 线程“ main”中的异常:java.lang.OutOfMemoryError:<原因> <堆栈跟踪>(本机方法)
    这表明本机方法遇到分配失败。 根本原因是该错误发生在JNI中,而不是在JVM内部执行的代码中发生。 当本机代码不检查内存分配错误时,应用程序将崩溃而不是耗尽内存。

内存泄漏的定义

“将内存泄漏视为一种疾病,而将OutOfMemoryError视为一种症状。 但是,并非所有OutOfMemoryErrors都暗示内存泄漏,并且并非所有内存泄漏都将自身表现为OutOfMemoryErrors。 ”

在《计算机科学》中,内存泄漏是一种资源泄漏,当计算机程序错误地管理内存分配以致不再释放不再需要的内存时,就会发生这种情况。 在面向对象的编程中 ,当对象存储在内存中但无法被运行的代码访问时,可能会发生内存泄漏。

Java中内存泄漏的常见定义:

当不必要的对象引用被不必要地维护时,就会发生内存泄漏。

在Java中,内存泄漏是指某些对象不再被应用程序使用,但是GC无法将其识别为未使用的情况。

当程序中不再使用某个对象,但仍在无法访问的某个位置引用该对象时,将出现内存泄漏。 因此,垃圾收集器无法删除它。 用于此对象的内存空间不会释放,并且用于程序的总内存将增加。 随着时间的推移,这将降低性能,并且JVM可能会耗尽内存。

从某种意义上说,当在永久性空间上无法分配任何内存时,就会发生内存泄漏。

内存泄漏的一些最常见原因是:

  1. 线程局部变量
  2. 圆形和复杂双向参考
  3. JNI内存泄漏
  4. 可变的静态字段(最常见)

我建议使用与JDK捆绑在一起Visual VM,以开始调试内存泄漏问题。

内存泄漏的常见调试

  1. NetBeans探查器
  2. 使用jhat实用程序
  3. 创建堆转储
  4. 在运行过程中获取堆直方图
  5. 在OutOfMemoryError处获取堆直方图
  6. 监视即将完成的对象数量
  7. 第三方内存调试器

调试内存泄漏问题的常用策略或步骤包括:

  • 识别症状
  • 启用详细垃圾回收
  • 启用分析
  • 分析痕迹

祝幸福时光,解决Java内存问题!

翻译自: https://www.javacodegeeks.com/2015/11/java-memory-architecture-model-garbage-collection-and-memory-leaks.html

Java内存体系结构(模型),垃圾回收和内存泄漏相关推荐

  1. 【Android 内存优化】垃圾回收算法 ( 内存优化总结 | 常见的内存泄漏场景 | GC 算法 | 标记清除算法 | 复制算法 | 标记压缩算法 )

    文章目录 一. 内存优化总结 二. 常见的内存泄漏场景 三. 内存回收算法 四. 标记-清除算法 ( mark-sweep ) 五. 复制算法 六. 标记-压缩算法 一. 内存优化总结 内存泄漏原理 ...

  2. 【java虚拟机序列】java中的垃圾回收与内存分配策略

    在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...

  3. java内存垃圾_Java内存区域与垃圾回收

    1,Java内存区域 1.1,运行时数据区域 java虚拟机在java的执行过程中将其管理的内存划分若干区域,有的随虚拟机进程的启动而一直存在,有的则依赖线程的启动和结束而建立和销毁. 1.1.1,程 ...

  4. java 虚拟机 Java内存结构 JVM垃圾回收机制算法

    什么是HotSpot VM 提起HotSpot VM,相信所有Java程序员都知道,它是Sun JDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机. 但不一定所有人都知道的是, ...

  5. JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)

    转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...

  6. JVM垃圾回收系列--内存模型/垃圾回收流程

    原文网址:JVM垃圾回收系列--内存模型/垃圾回收流程_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Java各个代的关系(内存模型)及垃圾收集流程. 内存模型 JDK8的内存模型 在Java中所有 ...

  7. java内存 海子_Java垃圾回收机制 - 海 子

    Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联系起来.在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给 ...

  8. 【Java 虚拟机原理】垃圾回收算法 ( Java 虚拟机内存分区 | 垃圾回收机制 | 引用计数器算法 | 引用计数循环引用弊端 )

    文章目录 一.Java 虚拟机内存分区 二.垃圾回收机制 三.引用计数器算法 ( 无法解决循环引用问题 ) 一.Java 虚拟机内存分区 Java 虚拟机内存分区 : 所有线程共有的内存区域 : 堆 ...

  9. java 全局变量 内存不回收_JAVA知识梳理:内存管理与垃圾回收机制

    相对于C,C++来说,java程序员最幸运的事就是不用进行内存控制,很少会出现内存溢出的异常.但是这也不是绝对的,当出现oom的时候,如果不了解虚拟机是如何使用内存的,排查错误将会成为一项艰难的任务. ...

  10. 详解JVM内存管理与垃圾回收机制5 - Java中的4种引用类型

    在Java语言中,除了基础数据类型的变量以外,其他的都是引用类型,指向各种不同的对象.在前文我们也已经知道,Java中的引用可以是认为对指针的封装,这个指针中存储的值代表的是另外一块内存的起始地址(对 ...

最新文章

  1. Loadrunner进行md5加密方法
  2. Androidstudio下Generate signed apk提示Error: Expected resource of type id [ResourceType]解决办法...
  3. 如何添加java环境变量_如何配置java环境变量
  4. Python 学习第十六天 html 前端内容总结
  5. linux别名文件位置,Linux系统内置alias别名文件路径
  6. python 调用bat失败_要想顺利通过Python面试,你最起码需要达到白银段位!
  7. 【UVA - 10037】Bridge(过河问题,经典贪心)
  8. KLite 移植说明 V1.0
  9. log4j的详细介绍
  10. html5游戏网页代码大全,HTML网页代码大全
  11. 《算法设计与分析》黄宇编著 课后习题参考答案
  12. 编译原理-第一节(东南大学廖力老师)
  13. OpenCv4在Win10 VS2019上环境搭建
  14. linux 使用 雅黑字体,linux 使用微软雅黑字体
  15. 家庭组网:Vlan单线复用,故障检测以及五种“软路由”加mesh组网方案
  16. Nginx架构四之七层负载均衡
  17. 数值分析-线性方程组的迭代法
  18. Presenting view controllers on detached view controllers is discouraged
  19. C语言的OOP实践(OOC)
  20. RS-232接口标准(串口)

热门文章

  1. 用一年的时间,依靠SEO创造一个成功的网站
  2. java操作字符串——CSDN博客
  3. 2的负x次幂图像_数学| NO.2,3 函数 T15
  4. 使用navicat 复制 数据库 使用mysql5.7 utf8mb4 utf8mb4_general_ci 爬虫的时候就支持表情包了
  5. javabean与json转换(fastjson与jackson两个版本)
  6. 云服务器的优点和缺点_为什么要使用云计算? 的优点和缺点
  7. fluent design_Fluent Design单选按钮,复选框,选择框,Java菜单
  8. pcf8523_PCF上的Spring Cloud合同和Spring Cloud Services
  9. jax-rs jax-ws_信守承诺:针对JAX-RS API的基于合同的测试
  10. c#发送讯息_企业讯息