我公司一兄弟,在controller层,每次调用controller的时候都创建了velocity引擎,而且没有去关闭,最终导致的现象就是jvm的内存信息正常,但是jvm之外的内存发生了泄露,导致是用jvm工具无法定位问题 最终使用对可能有问题的接口进行压测,发现了某个接口有问题,然后通过review代码发现了该问题.…
解Bug之路-记一次JVM堆外内存泄露Bug的查找 前言 JVM的堆外内存泄露的定位一直是个比较棘手的问题.此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤了Bug的源头.笔者将此Bug分析的过程写成博客,以飨读者. 由于物理内存定量分析部分用到了linux kernel虚拟内存管理的知识,读者如果有兴趣了解请看ulk3(<深入理解linux内核第三版>) 内存泄露Bug现场 一个线上稳定运行了三年的系统,从物理机迁移到docker环境后,运行了一段…
前言 记录一次线上JVM堆外内存泄漏问题的排查过程与思路,其中夹带一些JVM内存分配机制以及常用的JVM问题排查指令和工具分享,希望对大家有所帮助. 在整个排查过程中,我也走了不少弯路,但是在文章中我仍然会把完整的思路和想法写出来,当做一次经验教训,给后人参考,文章最后也总结了下内存泄漏问题快速排查的几个原则. 本文的主要内容: 故障描述和排查过程 故障原因和解决方案分析 JVM堆内内存和堆外内存分配原理 常用的进程内存泄漏排查指令和工具介绍和使用 文章撰写不易,请大家多多支持我的原创技术公众号…
一 JVM堆外内存 1)java与io(file,socket)的操作都需要堆外内存与jvm内存进行互相拷贝,因为操作系统是不懂jvm的内存结构的(jvm的内存结构是自管理的),所以堆外内存存放的是操作系统可以操作的内存地址模型,可以拷贝数据到内核的空间. 2)netty等网络通信组件为了减少jvm的内存到内核数据拷贝,所以把与网络相关的数据可以存放到堆外内存,减少一次内存的拷贝. 3)堆外内存是不属于jvm管理的,但是堆外内存是当前jvm进程的空间,而不是有的网络上所说的内核空间,内核地址是供…
首先确认堆占用 jmap 查看heap内存使用情况 jmap -heap pid 1 可以查看到MetaspaceSize,CompressedClassSpaceSize,MaxMetaSize jmap和jdk版本有关系,有些jdk版本会查看不到内存信息,可以使用jstat来查看统计信息 jstat 收集统计信息 jstat -gc pid 1000 1 S0C/S0U S1C/S1U EC/EU CCSC/CCSU YGC/YGCT FGC/FCGT GCTsurvivor0容量和使用 s…
看了不少资料,总结下: 堆外内存 / 直接内存(Direct Memory)JDK1.4中引入的NIO类,基于channel和Buffer的I/O方式,可用Native库直接分配堆外内存,然后利用一个存储在堆中的DirectByteBuffer对象作为这块内存引用来操作.避免了在Java堆和Native堆中来回复制数据. 优点 1.堆外内存不影响 JVM GC,程序会减少 Full GC. 2 IO 操作使用堆外内存比堆内存快.因为堆内在flush到远程时,会先复制到直接内存(非堆内存),然后在…
JVM初探-使用堆外内存减少Full GC 标签 : JVM 问题: 大部分主流互联网企业线上Server JVM选用了CMS收集器(如Taobao.LinkedIn.Vdian), 虽然CMS可与用户线程并发GC以降低STW时间, 但它也并非十分完美, 尤其是当出现Concurrent Mode Failure由并行GC转入串行时, 将导致非常长时间的Stop The World(详细可参考JVM初探- 内存分配.GC原理与垃圾收集器). 解决: 由GCIH可以联想到: 将长期存活的对象(如L…
一.前述 Spark中调优大致分为以下几种 ,代码调优,数据本地化,内存调优,SparkShuffle调优,调节Executor的堆外内存. 二.具体    1.代码调优 1.避免创建重复的RDD,尽量使用同一个RDD 2.对多次使用的RDD进行持久化 如何选择一种最合适的持久化策略? 默认情况下,性能最高的当然是MEMORY_ONLY,但前提是你的内存必须足够足够大,可以绰绰有余地存放下整个RDD的所有数据.因为不进行序列化与反序列化操作,就避免了这部分的性能开销:对这个RDD的后续算子操作,…
Native Memory Tracking (NMT) 是Hotspot VM用来分析VM内部内存使用情况的一个功能.我们可以利用jcmd(jdk自带)这个工具来访问NMT的数据. NMT介绍 工欲善其事必先利其器,我们先把相关需要的配置和工具介绍清楚,再通过例子来看看具体如何使用NMT. 打开NMT NMT必须先通过VM启动参数中打开,不过要注意的是,打开NMT会带来5%-10%的性能损耗. -XX:NativeMemoryTracking=[off | summary | detail]…
内存泄漏 内存泄漏是指程序在申请内存后,无法释放已申请的内存空间,无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费.内存泄漏最终会导致OOM. 造成内存泄漏典型场景: 1. 单例模式的不正确使用单例对象在初始化后将在JVM的整个生命周期中以静态变量的方式存在.如果单例对象持有对外部对象的引用,那么这个对象将不能被JVM正常回收 2. 数据库.网络.IO连接没有被关闭释放这类连接,一般会提供close方法进行显式关闭.但如果没有进行close,是不会自动…
导读 Netty 是一个异步事件驱动的网络通信层框架,用于快速开发高可用高性能的服务端网络框架与客户端程序,它极大地简化了 TCP 和 UDP 套接字服务器等网络编程. Netty 底层基于 JDK 的 NIO,我们为什么不直接基于 JDK 的 NIO 或者其他NIO框架: 使用 JDK 自带的 NIO 需要了解太多的概念,编程复杂. Netty 底层 IO 模型随意切换,而这一切只需要做微小的改动. Netty自带的拆包解包,异常检测等机制让我们从 NIO 的繁重细节中脱离出来,只需关心业务逻…
对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收:而使用的内存是由JVM控制的. 那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM给的内存不够用,怎么办? 此时,堆外内存登场!利用堆外内存,不仅可以随意操控内存,还能提高网络交互的速度. 背景1:JVM内存的分配 对于JVM的内存规则,应该是老生常谈的东西了,这里我就简单的说下: 新生代:一般来说新创建的对象都分配在这里. 年老代:经过几次垃圾回收,新生代的对象就会放在年老代里…
JVM源码分析之堆外内存完全解读   寒泉子 2016-01-15 17:26:16 浏览6837 评论0 阿里技术协会 摘要: 概述 广义的堆外内存 说到堆外内存,那大家肯定想到堆内内存,这也是我们大家接触最多的,我们在jvm参数里通常设置-Xmx来指定我们的堆的最大值,不过这还不是我们理解的Java堆,-Xmx的值是新生代和老生代的和的最大值,我们在jvm参数里通常还会加一个参数-XX:MaxPermSize来指定持久 概述 广义的堆外内存 说到堆外内存,那大家肯定想到堆内内存,这也是我们大…
内存溢出: 就是我们通常遇到的OutOfMemoryError异常,它俗理解就是内存不够,通常在运行大型程序时发生,当程序所需要的内存远远超出了JVM内存所承受大小,就会报出OutOfMemoryError异常(称为OOM异常). 在我们的JVM内存区域中(可以点击链接了解详情),除了程序计数器所占的内存其他的内存区域都有可能发生OOM异常,当发生OOM异常时我们可以通过Jstack工具和图形化工具JConsole工具查询到发生异常的具体区域. 当然也可以从以下几个方面来检查自己的程序: 是否存…
jvm堆外直接内存实现高性能接入层https://blog.csdn.net/phil_code/article/details/69056086…
作者:梦工厂链接:https://www.jianshu.com/p/7ebbe102c1ae来源:简书简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处. Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来. Java虚拟机在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域.   java虚拟机运行时数据区 一.程序计数器 程序计数器可以看做是当前线程所执行的字节码的行号指示器.在JVM的概念模型里,字…
小结: 检索词:C++内存分配器.jvm内存模型.gdb.内存泄露 https://tech.meituan.com/2019/01/03/spring-boot-native-memory-leak.html 2019年01月03日 作者: 纪兵 文章链接 5156字 11分钟阅读 2019年01月03日 作者: 纪兵 文章链接 5156字 11分钟阅读 背景 为了更好地实现对项目的管理,我们将组内一个项目迁移到MDP框架(基于Spring Boot),随后我们就发现系统会频繁报出Swap区域…
Java堆外内存管理   1.JVM可以使用的内存分外2种:堆内存和堆外内存: 堆内存完全由JVM负责分配和释放,如果程序没有缺陷代码导致内存泄露,那么就不会遇到java.lang.OutOfMemoryError这个错误. 使用堆外内存,就是为了能直接分配和释放内存,提高效率.JDK5.0之后,代码中能直接操作本地内存的方式有2种:使用未公开的Unsafe和NIO包下ByteBuffer. 使用ByteBuffer分配本地内存则非常简单,直接ByteBuffer.allocateDirect(…
在nio以前,是没有光明正大的做法的,有一个work around的办法是直接访问Unsafe类.如果你使用Eclipse,默认是不允许访问sun.misc下面的类的,你需要稍微修改一下,给Type Access Rules里面添加一条所有类都可以访问的规则: 在使用Unsafe类的时候: Unsafe f = Unsafe.getUnsafe(); 发现还是被拒绝了,抛出异常: java.lang.SecurityException: Unsafe 正如Unsafe的类注释中写道: Altho…
一.JVM内存的分配及垃圾回收 对于JVM的内存规则,应该是老生常谈的东西了,这里我就简单的说下: 新生代:一般来说新创建的对象都分配在这里. 年老代:经过几次垃圾回收,新生代的对象就会放在年老代里面.年老代中的对象保存的时间更久. 永久代:这里面存放的是class相关的信息,一般是不会进行垃圾回收的. JVM垃圾回收 由于JVM会替我们执行垃圾回收,因此开发者根本不需要关心对象的释放.但是如果不了解其中的原委,很容易内存泄漏,只能两眼望天了! 垃圾回收,大致可以分为下面几种: Minor GC…
一.JVM截图及概念 图1:JVM虚拟机运行时数据区域概念模型 1.程序计数器:内存空间中的一块小区域,作为当前线程所执行的字节码的行号指示器,注:如果是native方法,计数器为空 2.虚拟机栈:线程私有,生命周期与线程相同,虚拟机栈描述的是Java方法执行的内存模型:创建栈帧,用于存储局部变量表.操作数栈.动态链接.方法出口等信息 3.本地方法栈:和虚拟机栈功能类似,虚拟机使用本地Native方法服务 4.Java堆:线程共享,用于存放对象,是GC的主要管理区域 5.方法区:线程共享,用于存…
上篇文章介绍了Netty内存模型原理,由于Netty在使用不当会导致堆外内存泄漏,网上关于这方面的资料比较少,所以写下这篇文章,专门介绍排查Netty堆外内存相关的知识点,诊断工具,以及排查思路提供参考 现象 堆外内存泄漏的现象主要是,进程占用的内存较高(Linux下可以用top命令查看),但Java堆内存占用并不高(jmap命令查看),常见的使用堆外内存除了Netty,还有基于java.nio下相关接口申请堆外内存,JNI调用等,下面侧重介绍Netty堆外内存泄漏问题排查 堆外内存释放底层实现…
前言 通过学习深入理解java虚拟机的教程,以及自己在网上的查询的资料,做一个对jvm学习过程中的小总结. 本文章内容首先讲解java的内存分布区域,之后讲内存的分配原则以及内存的监控工具.再下来会着重讲解垃圾回收这一章节,该章节涉及了垃圾的标记算法以及各种垃圾回收算法,然后大概的介绍下市面上使用的垃圾收集器.之后就总结下上面的原理,讲解相关的jvm调优案例.然后会着重讲解类加载过程.最后一章讲字节码的部分,字节码相对来说是比较枯燥而且特别繁琐的内容,最好是自己动手配合着学习会好一点,或者观其大…
目录 1 JVM的内存区域布局 2 JVM五大数据区域介绍 3 JVM运行时内存布局和JMM内存模型区别 4 JMM内存模型交互操作 欢迎指正文中错误 关注公众号,一起交流 参考文章 1 JVM的内存区域布局 java代码的执行步骤有三点 java源码文件->编译器->字节码文件 字节码文件->JVM->机器码 机器码->系统CPU执行 JVM执行的字节码需要用类加载来载入:字节码文件可以来自本地文件,可以在网络上获取,也可以实时生成.就是说你可以跳过写java代码阶段,直接…
小结: 检索词:C++内存分配器.jvm内存模型.gdb.内存泄露 https://tech.meituan.com/2019/01/03/spring-boot-native-memory-leak.html 2019年01月03日 作者: 纪兵 文章链接 5156字 11分钟阅读 背景 为了更好地实现对项目的管理,我们将组内一个项目迁移到MDP框架(基于Spring Boot),随后我们就发现系统会频繁报出Swap区域使用量过高的异常.笔者被叫去帮忙查看原因,发现配置了4G堆内内存,但是实际…
一.前言 经过前面的学习,我们终于进入了虚拟机最后一部分的学习,内存模型.理解内存模型对我们理解虚拟机.正确使用多线程编程提供很大帮助.下面开始正式学习. 二.Java并发基础 在并发编程中存在两个关键问题①线程之间如何通信 ②线程之间如何同步. 2.1 通信 通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信. 在消息传递的并发模型里,线程之间…
原文转载自:http://my.oschina.net/sunchp/blog/369707 1.JVM内存模型 JVM运行时内存=共享内存区+线程内存区 1).共享内存区 共享内存区=持久带+堆 持久带=方法区+其他 堆=Old Space+Young Space Young Space=Eden+S0+S1 (1)持久带 JVM用持久带(Permanent Space)实现方法区,主要存放所有已加载的类信息,方法信息,常量池等等. 可通过-XX:PermSize和-XX:MaxPermSiz…
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWl3dXpoaWxpbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" width="700" height="400" alt=""> JVM体系主要包括下面部分: 类载入器.运行引擎,内存区.本地方法调用. 内存区一般即指执行…
Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM)用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果(“即Java程序的 write once run anywhere”). 在此之前,主流程序语言(如C/C++等)直接使用物理硬件和操作系统的内存模型,因此,会由于不同平台上内存模型的差异,在某些场景就必须针对不同的平台来编写程序. 1.主内存和工作内存 Java内存模型的主要目标是定义程序中各个变量的访问…
JVM运行时内存组成分为一些线程私有的,其他的是线程共享的. 线程私有 程序计数器:当前线程所执行的字节码的行号指示器. Java虚拟机栈:java方法执行的内存模型,每个方法被执行时都会创建一个栈帧,存储局部变量表,操作栈,动态链接,方法出口等信息.每个线程都有自己独立的栈空间,线程栈只存储基本类型和对象地址,方法中局部变量存放在线程空间中. 本地方法栈:Native方法服务,在hotspot虚拟机中和java虚拟机栈合二为一. 线程共享 java堆:存放对象实力,几乎所有的对象实例及其属性都…