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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356660.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1101. 献给阿尔吉侬的花束(bfs找最短路径)

题目&#xff1a; 1101. 献给阿尔吉侬的花束 - AcWing题库 输入样例&#xff1a; 3 3 4 .S.. ###. ..E. 3 4 .S.. .E.. .... 3 4 .S.. #### ..E.输出样例&#xff1a; 5 1 oop! 思路&#xff1a;bfs宽搜 用队列实现bfs。踢出队列头&#xff0c;并在队列尾插入与对头相关的…

与JBoss BPM Travel Agency更新了现代BPM数据集成

不久前&#xff0c;我们启动了一个规模较大的JBoss Travel Agency演示项目&#xff0c;以展示JBoss BPM Suite的一些更有趣的功能。 我们提供了一系列视频 &#xff0c;不仅向您展示了如何安装它&#xff0c;项目中各种规则和流程工件的含义&#xff0c;还向您介绍了在实际使用…

codeblock不能调试

问题&#xff1a;codeblock 不能调试&#xff0c;如下图&#xff1a; 解决方法&#xff1a; 首先&#xff0c;项目的保存路径不能是中文路径。 其次&#xff0c;必须创建工程。 最后&#xff0c;build选项里select target选成debug codeblock如何创建工程&#xff1a;http://j…

网络语言不c,哪些网络用语不文明?

满意答案林昨末sk2013.02.26采纳率&#xff1a;47% 等级&#xff1a;11已帮助&#xff1a;8049人Q1. 你认为在网络上出现的不文明用语情况_B___&#xff1f;A.是人们宣泄情绪的一种重要方式 B.是当今社会的一个缩影&#xff0c;没有办法C.不应当提倡&#xff0c;应加大管理力…

谷歌发布最新版安卓Android,谷歌正式除名华为,安卓12华为首发无望,但鸿蒙将迎难顶上!...

原标题&#xff1a;谷歌正式"除名"华为&#xff0c;安卓12华为首发无望&#xff0c;但鸿蒙将迎难顶上&#xff01;前几天谷歌正式发布了新一代的安卓12系统。这也是安卓的第十二个大更新版本&#xff0c;从安卓1.0发布的2008年算起&#xff0c;安卓系统已经走过13个年…

未知的生成错误 因为没有预加载,所以无法解析程序集 GalaSoft.MvvmLight

使用wpf开发时&#xff0c;在ViewModel中引用了DevExpress注册的GalaSoft.MvvmLight命名空间&#xff0c;使用其ViewModelBase&#xff0c;在View界面中绑定事件时出现错误&#xff1a; 错误 13 未知的生成错误“因为没有预加载&#xff0c;所以无法解析程序集“GalaSoft.MvvmL…

android 副mic测试,【收藏】Android Audio Framework CTS Verifier 测试方法

This new suite of tests requires human intervention and some external hardware including a Loopback Plug, a USB reference microphone and external speakers. For devices without 3.5 mm (⅛”) headset port, the user will be able to skip the test and mark it a…

魅蓝android底层是什么,魅蓝E2的手机系统是什么

魅蓝E2的手机系统是什么魅蓝E2的手机系统是Flyme 6系统。魅蓝E2搭载了基于YunOS底层深度定制的Flyme 6系统&#xff0c;相交于Flyme 5系列&#xff0c;Flyme 6拥有更轻巧明快的设计元素&#xff0c;辅以让人称颂的人工智能技术One Mind&#xff0c;可以有效保障魅蓝E2日常使用流…

android夜间模式揭露动画,Android Material Design系列之夜间模式

今天我们讲讲夜间模式的实现&#xff0c;这篇文章的名字应该叫&#xff1a;《Android Material Design系列之夜间模式》。在Android 5.0 之后&#xff0c;实现夜间模式并非很难了&#xff0c;支持的5.0库提供了非常简单的实现方式。不信&#xff0c;你就往下看。首先说&#xf…

jboss drools_JBoss Drools –入门

jboss drools这篇文章是关于我如何掌握JBoss Drools的 。 其背后的原因是&#xff1a;SAP收购了我公司当前的规则引擎&#xff0c;而Drools是我们将寻找的另一种选择&#xff0c;只要有人有能力提高概念验证的能力。 尽管似乎有大量的文档&#xff0c;但是我总是会通过示例来发…

华为荣耀30pro鸿蒙内测版,荣耀手机用户放心了 消息称荣耀30 Pro正在内测华为鸿蒙OS...

2021-5-11 13:12【天极网手机频道】鸿蒙OS2.0手机版目前正在大规模开发者公测阶段&#xff0c;有消息称6月份将开始大规模向华为手机用户推送。而对于不少荣耀手机用户来讲&#xff0c;他们也十分期待体验鸿蒙OS&#xff0c;但荣耀品牌已经与华为品牌分离&#xff0c;这让不少荣…

Docker容器中的WildFly Swarm JAX-RS微服务

这些天&#xff0c;每个人都在谈论微服务。 关于如何在企业级应用这些原则&#xff0c;有很多意见和想法&#xff0c;而很少有示例。 可以肯定的是&#xff0c;即使在几天前的会议上&#xff0c;我也很少发现有人在生产环境中运行Docker容器。 当我问起初次体验以及是否有人玩过…

C#解析json文件的方法

C# 解析 json JSON(全称为JavaScript Object Notation) 是一种轻量级的数据交换格式。它是基于JavaScript语法标准的一个子集。 JSON采用完全独立于语言的文本格式&#xff0c;可以很容易在各种网络、平台和程序之间传输。JSON的语法很简单&#xff0c;易于人阅读和编写&#x…

spring 线程池_Spring线程池服务

spring 线程池线程池对于执行同步和异步过程非常重要。 本文介绍如何使用Spring开发和监视线程池服务。 创建线程池已通过两种替代方法进行了说明。 二手技术 &#xff1a; JDK 1.6.0_21 春天3.0.5 Maven的3.0.2 步骤1&#xff1a;建立已完成的专案 创建一个Maven项目&…

带有骆驼,ActiveMQ,Elasticsearch的HL7关键用例

对于可以说HL7协议格式的系统&#xff0c; HL7 over MLLP是一种非常常见的传输机制。 JBoss Fuse是一个非常强大的微服务样式集成平台&#xff0c;在为关键医疗保健提供者构建灵活&#xff0c;有弹性&#xff0c;高可用性的集成方案方面拥有良好的记录。 此外&#xff0c;在JCA…

android 包裹内容,Android开发中Bundle用法 包裹数据

SDK里是这样描述&#xff1a;A mapping from String values to various Parcelable types。它帮助我将数据打包传入intent里面&#xff0c;为使用这些数据提供了便利。protected void onListItemClick (ListView l, View v, int position, long id){super.onListItemClick(l, v…

安卓高级6 SnackBar

引言 文&#xff0f;李牧羊&#xff08;简书作者&#xff09; 原文链接&#xff1a;http://www.jianshu.com/p/2654e6bda3b1 著作权归作者所有&#xff0c;转载请联系作者获得授权&#xff0c;并标注“简书作者”。 在之前我有提到这一篇Android Design Support Library系列文章…

利用Aspose.Word控件实现Word文档的操作

Aspose系列的控件&#xff0c;功能都挺好&#xff0c;之前一直在我的Winform开发框架中用Aspose.Cell来做报表输出&#xff0c;可以实现多样化的报表设计及输出&#xff0c;由于一般输出的内容比较正规化或者多数是表格居多&#xff0c;所以一般使用Aspose.Cell来实现我想要的各…

html编码自动识别,html实体编码遇上js代码

摘要&#xff1a; 在js中单、双引号引起来的是字符串&#xff0c;如果我们要在字符串中使用单、双引号&#xff0c;需要反斜杠进行转义。而如果字符串出现在html标签中&#xff0c;我们需要做转义处理。单双引号在js代码中在js中单、双引号引起来的是字符串&#xff0c;如果我们…

Activiti中具有单独数据库模式的多租户

我们过去听到的一项功能请求是以多租户方式运行Activiti引擎&#xff0c;使租户的数据与其他租户的数据隔离。 当然&#xff0c;在某些云/ SaaS环境中&#xff0c;这是必须的。 几个月前&#xff0c;波恩大学的学生拉斐尔吉伦&#xff08;Raphael Gielen&#xff09;与我接触&…