1. 内存模型以及分区

JVM内存模型如下图所示:
此处我们集中注意中间绿色的部分,该部分为JVM的运行时内存,该部分包含了:
线程私有的(灰色):
  1. 程序计数器:记录执行到第几条指令
  2. 虚拟机方法栈:执行Java方法所用,每执行一个方法便加入一个栈帧,里面含有局部变量表、操作栈、动态链接和方法出口等
  3. 本地方法栈:与虚拟机方法栈相似,用于执行native方法
线程共享的(蓝色):
  1. 堆:对象实例存放地,,分为年轻代和老年代。年轻代又细分为伊甸园区和两个相对的Survival区
  2. 方法区:也叫永久代,存放了类的信息、常量、类静态变量等元素,含有一个运行时常量池
 

2. 堆里面的分区:Eden,survival from to,老年代,各自的特点

1.Eden区

Eden区位于Java堆的年轻代,是新对象分配内存的地方,由于堆是所有线程共享的,因此在堆上分配内存需要加锁。而Sun JDK为提升效率,会为每个新建的线程在Eden上分配一块独立的空间由该线程独享,这块空间称为TLAB(Thread Local Allocation Buffer)。在TLAB上分配内存不需要加锁,因此JVM在给线程中的对象分配内存时会尽量在TLAB上分配。如果对象过大或TLAB用完,则仍然在堆上进行分配。如果Eden区内存也用完了,则会进行一次Minor GC(young GC)。
 

2.Survival from to

Survival区与Eden区相同都在Java堆的年轻代。Survival区有两块,一块称为from区,另一块为to区,这两个区是相对的,在发生一次Minor GC后,from区就会和to区互换。在发生Minor GC时,Eden区和Survival from区会把一些仍然存活的对象复制进Survival to区,并清除内存。Survival to区会把一些存活得足够旧的对象移至年老代。
 

3.年老代

年老代里存放的都是存活时间较久的,大小较大的对象,因此年老代使用标记整理算法。当年老代容量满的时候,会触发一次Major GC(full GC),回收年老代和年轻代中不再被使用的对象资源。
 
 
ADD:4.能说明minor gc/full gc的触发条件、OOM的触发条件,降低GC的调优的策略。 
       分析:列举一些我期望的回答:eden满了minor gc,升到老年代的对象大于老年代剩余空间full gc,或者小于时被HandlePromotionFailure参数强制full gc;gc与非gc时间耗时超过了GCTimeRatio的限制引发OOM,调优诸如通过NewRatio控制新生代老年代比例,通过MaxTenuringThreshold控制进入老年前生存次数等……

3. 对象创建方法,对象的内存分配,对象的访问定位

对象的创建

Java对象的创建大致上有以下几个步骤:
  1. 类加载检查:检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类的加载过程
  2. 为对象分配内存:对象所需内存的大小在类加载完成后便完全确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。由于堆被线程共享,因此此过程需要进行同步处理(分配在TLAB上不需要同步)
  3. 内存空间初始化:虚拟机将分配到的内存空间都初始化为零值(不包括对象头),内存空间初始化保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
  4. 对象设置:JVM对对象头进行必要的设置,保存一些对象的信息(指明是哪个类的实例,哈希码,GC年龄等)
  5. init:执行完上面的4个步骤后,对JVM来说对象已经创建完毕了,但对于Java程序来说,我们还需要对对象进行一些必要的初始化。

对象的内存分配

Java对象的内存分配有两种情况,由Java堆是否规整来决定(Java堆是否规整由所采用的垃圾收集器是否带有压缩整理功能决定):
  1. 指针碰撞(Bump the pointer):如果Java堆中的内存是规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,分配内存也就是把指针向空闲空间那边移动一段与内存大小相等的距离
  2. 空闲列表(Free List):如果Java堆中的内存不是规整的,已使用的内存和空闲的内存相互交错,就没有办法简单的进行指针碰撞了。虚拟机必须维护一张列表,记录哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录

对象的访问定位

对象的访问形式取决于虚拟机的实现,目前主流的访问方式有使用句柄和直接指针两种:

使用句柄:

如果使用句柄访问,Java堆中将会划分出一块内存来作为句柄池,引用中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自的具体地址信息:
优势:引用中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而引用本身不需要修改。

直接指针:

如果使用直接指针访问对象,那么对象的实例数据中就包含一个指向对象类型数据的指针,引用中存的直接就是对象的地址:
优势:速度更快,节省了一次指针定位的时间开销,积少成多的效应非常可观。
 

4. GC的两种判定方法:引用计数与引用链

基于引用计数与基于引用链这两大类别的自动内存管理方式最大的不同之处在于:前者只需要局部信息,而后者需要全局信息
 

引用计数

引用计数顾名思义,就是记录下一个对象被引用指向的次数。引用计数方式最基本的形态就是让每个被管理的对象与一个引用计数器关联在一起,该计数器记录着该对象当前被引用的次数,每当创建一个新的引用指向该对象时其计数器就加1,每当指向该对象的引用失效时计数器就减1。当该计数器的值降到0就认为对象死亡。每个计数器只记录了其对应对象的局部信息——被引用的次数,而没有(也不需要)一份全局的对象图的生死信息。由于只维护局部信息,所以不需要扫描全局对象图就可以识别并释放死对象;但也因为缺乏全局对象图信息,所以无法处理循环引用的状况。
 

引用链

引用链需要内存的全局信息,当使用引用链进行GC时,从对象图的“根”(GC Root,必然是活的引用,包括栈中的引用,类静态属性的引用,常量的引用,JNI的引用等)出发扫描出去,基于引用的可到达性算法来判断对象的生死。这使得对象的生死状态能批量的被识别出来,然后批量释放死对象。引用链不需要显式维护对象的引用计数,只在GC使用可达性算法遍历全局信息的时候判断对象是否被引用,是否存活。
 

5. GC的三种收集方法:标记清除、标记整理、复制算法的原理与特点,分别用在什么地方

标记清除

标记清除算法分两步执行:
  1. 暂停用户线程,通过GC Root使用可达性算法标记存活对象
  2. 清除未被标记的垃圾对象
标记清除算法缺点如下:
  1. 效率较低,需要暂停用户线程
  2. 清除垃圾对象后内存空间不连续,存在较多内存碎片
标记算法如今使用的较少了
 

复制算法

复制算法也分两步执行,在复制算法中一般会有至少两片的内存空间(一片是活动空间,里面含有各种对象,另一片是空闲空间,里面是空的):
  1. 暂停用户线程,标记活动空间的存活对象
  2. 把活动空间的存活对象复制到空闲空间去,清除活动空间
复制算法相比标记清除算法,优势在于其垃圾回收后的内存是连续的。
但是复制算法的缺点也很明显:
  1. 需要浪费一定的内存作为空闲空间
  2. 如果对象的存活率很高,则需要复制大量存活对象,导致效率低下
复制算法一般用于年轻代的Minor GC,主要是因为年轻代的大部分对象存活率都较低
 

标记整理

标记整理算法是标记清除算法的改进,分为标记、整理两步:
  1. 暂停用户线程,标记所有存活对象
  2. 移动所有存活对象,按内存地址次序一次排列,回收末端对象以后的内存空间
标记整理算法与标记清除算法相比,整理出的内存是连续的;而与复制算法相比,不需要多片内存空间。
然而标记整理算法的第二步整理过程较为麻烦,需要整理存活对象的引用地址,理论上来说效率要低于复制算法。
因此标记整理算法一般引用于老年代的Major GC

JVM常见问题 一(转载)的更多相关文章

  1. Java虚拟机详解----JVM常见问题总结

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  2. JVM常见问题分析

    JVM常见问题分析 启动,并且去查看日志 ./startup.sh && tail -f ../logs/catalina.out 常见有有以下几个问题: 1.java.lang.Ou ...

  3. JVM 垃圾回收- 转载 知识碎片

    最近关注了一下垃圾回收的问题,想了解一下JVM 关于方法区的垃圾回收机制,找了几篇文章,不同的文章从不同角度讲述了一下,嗯... 拼凑起来 记录一下, 有些未验证正确性... JVM 方法区 当JVM ...

  4. J2EE,J2SE,J2ME,JDK,SDK,JRE,JVM区别(转载)

    转载地址:http://blog.csdn.net/alspwx/article/details/20799017 一.J2EE.J2SE.J2ME区别 J2EE——全称Java 2 Enterpri ...

  5. 转:Jmeter常见问题 (转载) http://www.51testing.com/?uid-128005-action-viewspace-itemid-84094

    说明:这些问答是从网上转载的,自己修改了其中的一些内容,如果大家兴趣,可以将大家在使用Jmeter的时候碰到的问题写下来,我们一起补充到这个问答里面,共同努力完善jmeter的资料. 1.  JMet ...

  6. JVM常见问题(二)

    6. GC收集器有哪些?它们的特点是? 常见的GC收集器如下图所示,连线代表可搭配使用: 1.Serial收集器(串行收集器) 用于新生代的单线程收集器,收集时需要暂停所有工作线程(Stop the ...

  7. Jmeter(二十五)常见问题(转载)

    转载自 http://www.cnblogs.com/yangxia-test 收集工作中JMeter遇到的各种问题   1.  JMeter的工作原理是什么? 向服务器提交请求:从服务器取回请求返回 ...

  8. ESP8266常见问题汇总——转载自官网

    ESP8266 常见问题 本页面收集esp8266常见问题 概述 本文档主要介绍开发者在ESP8266开发中常见的一些问题. 这些问题主要包括以下几大类: 基本概念相关 ESP8266 相关 AiCl ...

  9. Hive SQL 常见问题(转载)

    http://www.aboutyun.com/thread-14942-1-1.html 问题导读 1.Hive查询语句和SQL查询语句区别与联系. 2.distribute by.group by ...

随机推荐

  1. SpringCloud是否值得引入?

    中小型互联网公司微服务实践-经验和教训 http://xujin.org/sc/sc-zq/#more Spring Cloud在国内中小型公司能用起来吗?https://mp.weixin.qq.c ...

  2. Python系列-python文件操作

    原链接:https://blog.csdn.net/m0_37745438/article/details/79573414 python提供了一系列方法来对文件进行读取.写入等操作 一.打开文件的方 ...

  3. 如何设置eclipse 右键new的菜单

    如何设置eclipse 右键new的菜单 在使用eclipse进行开发的时候,开发人员一般使用File-new来创建项目或文件,但常常发现,默认右键new选项里很多选项极少会用到,而一些常用的选项又没 ...

  4. Centos7 安装python3

    Centos7 安装python3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #安装sqlite-devel yum -y ...

  5. Hadoop:读取hdfs上zip压缩包并解压到hdfs的实现代码

    背景: 目前工作中遇到一大批的数据,如果不压缩直接上传到ftp上就会遇到ftp空间资源不足问题,没办法只能压缩后上传,上穿完成后在linux上下载.但是linux客户端的资源只有20G左右一个压缩包解 ...

  6. 用PHP如何实现这种乘法口诀表?

    用PHP如何实现这种乘法口诀表? 1x1=1 ,1x2=2 ,1x3=3 ,.....,1x9=9 2x2=4 ,2x3=6 ,......,2x9=18 ........ ...... 8x8=64 ...

  7. oracle11g中SQL优化(SQL TUNING)新特性之SQL Plan Management(SPM)

    1.   简介 Oracle Database11gR1引进了SQL PlanManagement(简称SPM),一套允许DBA捕获和保持任意SQL语句执行计划最优的新工具,这样,限制了刷新优化器统计 ...

  8. Python系列之 - 字符编码问题

    1.内存和硬盘都是用来存储的. CPU:速度快 硬盘:永久保存 2.文本编辑器存取文件的原理(nodepad++,pycharm,word) 打开编辑器就可以启动一个进程,是在内存中的,所以在编辑器编 ...

  9. jQuery中的事件监听小记

    一,一个事件监听的简便写法 最近发现一个jQuery中事件监听的简洁写法,感觉方便好多.同时也深感自己基础薄弱,好多东西竟然都模棱两可.因此,记录的同时,也对jQuery事件监听做个小的总结 原文链接 ...

  10. hive中No space left on device问题或者Java HotSpot(TM)64-Bit Server VM warning:Insufficient space for shared memory