jvm内存结构

更多参考:
一篇简单易懂的原理文章,让你把JVM玩弄与手掌之中
关于JVM的类型和模式
jvm系列 (一) ---jvm内存区域与溢出
JVM常量池浅析 --- 很棒
JVM 的 工作原理,层次结构 以及 GC工作原理
JVM内存分配及GC
Java8内存模型—永久代(PermGen)和元空间(Metaspace)
JVM第一篇:一个Java内存泄漏的排查案例

一、JVM运行时数据区(注意jdk1.6/1.7/1.8的区别)

  • 程序计数器: 每个线程享有一个程序计数器,当前线程执行字节码的行号指示器。分支、循环、跳转、异常处理和线程恢复等功能都依赖于程序计数器。
  • 虚拟机栈: stack属于线程私有,生命周期与线程相同。虚拟机栈描述了java方法执行的内存模型。用于java方法。
  • 本地方法栈: 用于native方法的stack。
  • 堆: 堆是所有线程共享的内存区域,用于存放所有的对象实例和数组,是垃圾回收管理的主要区域。
  • 方法区: 方法区用于存储已被虚拟机加载的类信息、常量、静态变量、编译器编译后的代码等数据。运行时常量池是方法区的一部分,用于存放编译器生成的各种字面量和符号引用。

可见,垃圾回收主要针对于方法区和堆内存;不针对虚拟机栈、本地方法栈和程序计数器,因为它们的生命周期与栈相同,随生随灭。

  • jdk1.8的JVM运行时数据区域概览

    1.8同1.7比,最大的差别就是:元数据区取代了永久代。元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元数据空间并不在虚拟机中,而是使用本地内存。

二、java内存模型

JVM内存分布模型包括了堆和方法区,方法区称为永久代(permanent generation),堆空间分为新生代(young generation)和老年代(old generation)。新生代则又可以分为Eden和Survivor两个区域。如图:

  • Eden Space (heap): 对象第一次申请内存所处的区域。
  • Survivor Space (heap): Eden Space的对象被垃圾收集一次,移动到Survivor Space。
  • Tenured Generation (heap): 在Survivor中存在了一段时间后,被移动到老年代。
  • Permanent Generation (non-heap): 方法区,存储着类信息、常量、静态变量、编译器编译后的代码等数据。

三、jvm参数设置

  • -Xmx:最大堆大小
  • -Xms:初始堆大小,即堆的最小内存
  • -Xmn:年轻代大小
  • -Xss:设置每个线程的堆栈大小
  • -XX:NewRatio:设置年轻代(包括Eden和两个Survivor区)与年老代的比值
  • -XXSurvivorRatio:年轻代中Eden区与Survivor区的大小比值(eden:from/to,eden跟from或to单个的比值,如3,表示3:1:1)
  • -XX:MaxNewSize:年轻代大小
  • -XX:MaxPermSize:永久代大小
  • -XX:MaxTenuringThreshold:设置对象从年轻代进入老年代的最大年龄

堆空间内存分配(默认情况下)

  • 老年代 : 三分之二的堆空间
  • 年轻代 : 三分之一的堆空间
    eden区: 8/10 的年轻代空间
    survivor0 : 1/10 的年轻代空间
    survivor1 : 1/10 的年轻代空间
-server -Xms1800m -Xmx1800m -Xmn680m -Xss256k -XX:MetaspaceSize=340m -XX:MaxMetaspaceSize=340m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+DisableExplicitGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Dcom.sun.management.jmxremote.port=9981 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/logs

四、内存溢出、内存泄漏

内存溢出与内存泄漏

  • 基本概念
  • 内存溢出:
    简单地说内存溢出就是指程序运行过程中申请的内存大于系统能够提供的内存,没有足够的内存空间供其使用,导致无法申请到足够的内存,于是就发生了内存溢出,出现out of memory;
  • 内存泄漏:
    内存泄漏指程序运行过程中分配内存给临时变量,用完之后却没有被GC回收,始终占用着内存,既不能被使用也不能分配给其他程序,于是就发生了内存泄漏,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
  • memory leak会最终会导致out of memory!
  • 内存溢出的常见情况
  • 1、java.lang.OutOfMemoryError: PermGen space (持久带溢出)
    我们知道jvm通过持久带实现了java虚拟机规范中的方法区,而运行时常量池就是保存在方法区中的,因此发生这种溢出可能是运行时常量池溢出,或是由于程序中使用了大量的jar或class,使得方法区中保存的class对象没有被及时回收或者class信息占用的内存超过了配置的大小。
  • 2、java.lang.OutOfMemoryError: Java heap space (堆溢出)
    发生这种溢出的原因一般是创建的对象太多,在进行垃圾回收之前对象数量达到了最大堆的容量限制。
    解决这个区域异常的方法一般是通过内存映像分析工具对Dump出来的堆转储快照进行分析,看到底是内存溢出还是内存泄漏。如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots的引用链,定位出泄漏代码的位置,修改程序或算法;如果不存在泄漏,就是说内存中的对象确实都还必须存活,那就应该检查虚拟机的堆参数-Xmx(最大堆大小)和-Xms(初始堆大小),与机器物理内存对比看是否可以调大。
  • 3、虚拟机栈和本地方法栈溢出
    如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError。
    如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError。
  • 三、内存泄漏

1、常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
2、偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。
3、一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。
4、隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。

  • 避免内存泄漏的几点建议:
    1、尽早释放无用对象的引用。
    2、避免在循环中创建对象。
    3、使用字符串处理时避免使用String,应使用StringBuffer。
    4、尽量少使用静态变量,因为静态变量存放在永久代,基本不参与垃圾回收。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356