JVM运行时内存区是如何划分的?

方法区(Method Area):存储类的字节码信息、常量池

堆区(Heap  Area):存储对象

Java方法栈(Stack Area):所有方法运行时,会创建一个栈帧对象,然后进入栈(方法栈)

本地方法栈(Native Method Stack Area):用C语言写的,方法执行时候,会进入本地方法栈

程序计数器(Pc Register):用于记录当前线程要执行的下一条字节码指定的地址

如何理解方法区(Method Area)?

方法区是逻辑一种定义,是一种规范,可被所有线程共享,不同JVM对方法区的落地实现可能不同,例如在JDK7中方法区称之为持久代,在JDK8中方法区叫元空间(Metaspace),并且这个元空间可以是JVM堆外的一块内存,不占用操作系统为JVM分配的内存。

如何理解JAVA中的堆(Heap),他的构成是怎样的?

Java中的堆是用于存储对象的一块区域,可被所有线程所共享。这块区域又可以分为年轻代和老年代,年轻代又分为伊甸园区和2个幸存区(有一块区域始终是空的)。

JVM虚拟机栈的结构是怎样的?

Java中每个线程都有一个虚拟机栈(Java方法栈)每个方法的执行都会对应着一次入栈(Push)和出栈(Pop)操作,栈中的元素为一个一个的栈帧(Stack Frame)对象,这个栈帧的构成主要有如下几部分:

1、操作数栈(用于执行运算)

2、局部变量表(用于存储方法内部的局部变量)

3、方法的返回值(存储方法的返回值)

4、动态链接(方法中要访问的一些常用池数据,要调用的方法,都会对应一个链接)

5、其他信息

如何理解程序计数器?

程序计数器用于记录当前线程要执行的下一条指令的偏移量地址,每个线程都有一个程序计数器,这个程序计数器也是所有内存中唯一一个不会出现内存溢出的区域

Java对象分配内存的一个基本过程是怎样的?

1、编译器通过逃逸分析(JDK8已默认开启)判定对象是在堆上分配还是在栈上分配

2、假如确定是在堆上分析,则可首先选择TLAB区,检测这块区域是否可以存储这个对象,可以则存储

3、假如TLAB区无法存储新创建的对象,则可以考虑在TLAB区之外的Eden区加锁分配(这里为什么加锁分配:申请分配内存的时候,有可能在java堆的同一个位置申请,这时就需要对拟分配的内存区域进行加锁或者采用CAS等操作,保证这个区域只能分配给一个线程)

4、如果Eden区无法存储对象,则执行Young GC(Minor)-年轻代的垃圾回收

5、假如Eden区执行了Young GC之后,仍然不足以存储对象,则直接分配到老年代。

6、假如老年代也不足以存储这个对象,则执行Full GC,这个过后还不能存储对象则抛出异常。

JVM中年轻代中幸存区设置的比例比较小,可能会产生什么问题?

年轻代的伊甸园区对象越来越多时,会启动Young GC,此时伊甸园区的对象就要拷贝到幸存区。假如这个幸存区比较小,无法存储从伊甸园区拷贝过来的幸存对象,此时这些对象就直接分配到老年代,就会导致老年代的对象越来越多,触发老年代GC的频率就变高,老年代的GC一般为Full GC,这个GC的时间会比较长,会影响系统的吞吐量和执行效率。说明:伊甸园区与两个幸存区的比例通常是8:1:1

假如伊甸园区设置的比例比较小,可能会出现什么问题?

我们创建的对象,大部分都是存储在伊甸园区。假如伊甸园区设置的比例小了,可能会增加GC频率。GC时,用户线程会出现短时间的暂停,这样会影响系统的执行性能。

JVM的堆内存为什么要分为年轻代和老年代?

通过分代设计,减少GC的空间范围,提高GC效率。

JVM调优中为什么推荐初始堆大小和最大堆大小要设置成一样的(-Xms2048m -Xms2048m)?

避免程序在运行过程中,因对象的多少或GC后内存的变化,进而导致的内存大小的调整,这个内存大小的调整的过程可能会带来更大的系统开销。(阿里的开发规范中)

 什么情况下对象可能会直接存储到老年代?

1、创建的对象比较大,年轻代没有空间存储这个对象。

2、年轻代GC时,活着对象比较多,幸存区存不下,此时这些对象可能会存储到老年代。

3、经过多次GC,没有被回收的对象,随着年龄的增加(默认是15)可能会移动到老年代。

Java中所有的对象都分配在堆上的,对吗?

随着技术的进步,这个说法已经不是那么准确了,对象可以分配在栈上了(小对象、未逃逸的对象可以分配在栈上)。

Java中的逃逸分析如何理解,可以解决什么问题?

逃逸分析本质是一种数据分析算法,基于这个算法判定对象是否发生了逃逸,未逃逸的对象可以直接分配在栈上、也可以执行标量替换。这样可以有效的减少对象在堆上的分配,进而减少阻塞、GC频率,提高执行效率。

如何理解Java中的标量替换技术,为什么要进行标量替换?

标量替换是一种将对象打散(将对象中成员以局部变量的方式进行设计)分配到栈上的技术,减少对象在堆中的创建次数,进而降低GC频率,提高其性能。

什么是内存溢出以及导致内存溢出的原因?

内存中剩余的内存空间不足以分配给新的内存请求,此时就会出现内存溢出。内存溢出可能会导致系统崩溃,具体可能导致内存溢出的原因有:

1、创建的对象太大。

2、创建的对象太多,又有大量的内存泄漏。

3、方法区的类太多了,没有足够的空间存储一些新的类型了。

4、方法出现了无限递归调用,可能会导致栈内存溢出。

什么是内存泄漏以及导致内存泄漏的原因?

程序中的对象在使用完毕之后,对象占有的内存空间,没有及时得到释放,一直占着内存空间,这个现象就称之为内存泄漏。常见的内存泄漏有:

1、缓存使用不当(例如缓存中对对象的引用都是强引用)。

2、内部类的使用不当(例如实例内存类会默认保存外部类引用)。

3、大量的IO连接操作没有及时得到关闭。

4、大量的使用static变量(这个的变量的生命周期不依赖于变量所在的类对象)。

Java中的四大引用有什么特点?

强引用:当内存不足时,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收。强引用是我们最常见的普通对象引用,只要还有强引用指向一个对象 ,就能表明这个对象还“活着”,垃圾回收器就不会碰这些对象。

软引用:软引用是一种相对弱化了一些的引用,需要用 java.lang.ref.SoftReference 类来实现,可以让对象豁免一些垃圾收集。对于只有软引用(还有用、但非必须)的对象来说,

1)当系统内存充足时他不会被回收。

2)当系统内存不足时他会被回收。

这个特性很适合用来实现缓存:比如网页缓存、图片缓存等... 内存够用就保留,不够用就回收,可以很好地来解决OOM问题。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。

弱引用:弱引用也是用来描述非必须对象,但是他的强度比软引用更弱一些。

如果你创建了一个仅持有弱引用的对象,那么下一次垃圾回收发生的时候,无论当前内存是否足够,这个对象都会被回收掉。在JDK1.2之后提供了 WeakReference 类来实现弱引用。

虚引用:虚引用也称为幻像引用,他是最弱的一种引用。如果一个对象仅持有幻像引用,那么他就和没有任何引用一样。对其生存时间没有任何影响,我们也无法通过幻像引用来取得一个对象实例。事实上,我们可以通过为一个对象设置为幻像引用关联从而跟踪这个对象被垃圾回收的活动。在JDK1.2之后提供了 PhantomReference 类来实现弱引用。

引用队列:引用队列 ReferenceQueue 是用来配合引用工作的,最常与幻像引用一起使用,因为幻像引用的构造函数必须指定引用队列,而其他引用类型没有引用队列一样可以运行。

当某个被引用的对象被回收的时候,JVM会指向他的引用加入到引用队列的队列末尾,这相当于是一种通知机制。这个操作其实是由 ReferenceHandler 守护线程来做的,这个守护线程是在Reference静态代码块中建立并且运行的线程,所以只要Reference 这个父类被初始化,该线程就会创建和运行,他的运行方法依赖了比较多的本地(native)方法。由于ReferenceHandler 是守护线程,除非JVM进程终结,否则他会一直在后台运行。

不同引用类型的应用场景:

1)软引用的应用:断路器

2)弱引用的应用:ThreadLocal的ThreadLocalMap实现的

3)虚引用的应用:数据库连接池(数据库连接池 Connection Pool 应该具备的一个优点就是能够有效的避免连接资源泄露,同时能够对连接资源进行回收)

JVM运行时内存区的更多相关文章

  1. Java内存管理:Java内存区域 JVM运行时数据区

    转自:https://blog.csdn.net/tjiyu/article/details/53915869 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些, ...

  2. JVM运行时数据区与JVM堆内存模型小结

    前提 JVM运行时数据区和JVM内存模型是两回事,JVM内存模型指的是JVM堆内存模型. 那JVM运行时数据区又是什么? 它包括:程序计数器.虚拟机栈.本地方法栈.方法区.堆. 来看看它们都是干嘛的 ...

  3. JVM运行时数据区及对象在内存中初始化的过程

    JVM运行时数据区 Java虚拟机所管理的内存区域,也称为运行时数据区,分为以下几个运行时数据区,如图所示 程序计数器:当前程序所执行字节码的行号指示器 程序计数器(Program Counter R ...

  4. JVM 运行时内存结构

      1.JVM内存模型       JVM运行时内存=共享内存区+线程内存区 1).共享内存区       共享内存区=持久带+堆       持久带=方法区+其他       堆=Old Space ...

  5. JVM运行时内存结构

    原文转载自:http://my.oschina.net/sunchp/blog/369707 1.JVM内存模型 JVM运行时内存=共享内存区+线程内存区 1).共享内存区 共享内存区=持久带+堆 持 ...

  6. JVM运行时内存组成分为一些线程私

    JVM运行时内存组成分为一些线程私有的,其他的是线程共享的. 线程私有 程序计数器:当前线程所执行的字节码的行号指示器. Java虚拟机栈:java方法执行的内存模型,每个方法被执行时都会创建一个栈帧 ...

  7. Jvm运行时数据区

    一:运行时数据区 Java虚拟机在执行Java程序的过程中会把它管理的内存分为若干个不同的数据区域.这些区域有着各自的用途,一级创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户 ...

  8. JVM 运行时数据区 (三)

    JVM运行时数据区 运行时数据区由 程序计数器.java虚拟机栈.本地方法栈.堆.方法区 组成: 1.程序计数器 每一个Java线程都有一个程序计数器,用于保存程序执行到当前方法的哪一个指令,它是线程 ...

  9. JVM总结(一):概述--JVM运行时数据区

    大三下,趁着寒假重温一遍JVM,准备在一个系列来总价一下学习JVM的整个过程.争取在接下来的一个星期内更新完这一个系列,然后回家过年. JVM运行时数据区 线程私有的数据区 程序计数器 虚拟机栈 本地 ...

  10. [转]JVM运行时内存结构

    [转]http://www.cnblogs.com/dolphin0520/p/3783345.html 目录[-] 1.为什么会有年轻代 2.年轻代中的GC 3.一个对象的这一辈子 4.有关年轻代的 ...

随机推荐

  1. CF1358D The Best Vacation

    题目传送门 思路 做这道题主要是需要发现一个性质:选择的区间必定是从某一个月的最后一天开始往前连续的一段区间. 考虑如何证明这个结论,设这个月有 \(x\) 天,假设有更优的方案满足到下一个月的第 \ ...

  2. JavaSE 对象与类(二)

    6.对象构造 重载:如果有多个方法(比如,StringBuilder构造器方法)有相同的名字.不同的参数.便产生了重载. 重载解析:编译器通过用各个方法给出的参数类型与特定方法调用所使用的值类型进行匹 ...

  3. CCRD_TOC_2008年第2期

    中信国健临床通讯 2008年第2期 目 录   类风湿关节炎 1. 纵向分析TEMPO数据:放射学损伤程度和进展速率决定了关节物理功能 van der Heijde D, et al. Ann Rhe ...

  4. 怎么下载blob视频 .mu38视频下载转换格式

    首先获取视频m3u8地址 浏览器按 F12进入开发者模式 选择 Network 搜索.m3u8 RequestURL 获取视频url m3u8文件介绍 M3U(Moving Picture Exper ...

  5. log 函数

    什么是对数 对数用 log 符号来表示.根据底数的不同,log 可以变换成 lg.ln.lg 是以 10 为底的对数,ln 是以 e 为底的对数. logax=y,是一个以 a 为底,x 为真数的对数 ...

  6. C#神器"BlockingCollection"类实现C#神仙操作

    前言 如果你想玩转C# 里面多线程,工厂模式,生产者/消费者,队列等高级操作,就可以和我一起探索这个强大的线程安全提供阻塞和限制功能的C#神器类 BlockingCollection简单介绍 微软介绍 ...

  7. windows-sam文件

    sam文件是账号密码的数据库文件 存放位置C:\Windows\System32\Config\sam

  8. CF1137F Matches Are Not a Child's Play 题解

    以最后被删去的点为根,这样子不会存在从父亲然后删掉某个点,儿子的删除顺序一定比父亲前. 记每个点子树中的最大值为 \(f_x\),那么一个点的排名,首先就需要加上 \(<f_x\) 的所有值,记 ...

  9. 设置点击事件时Unable to preventDefault inside passive event listener due to target being treated as passive

    问题 当使用fastClick.js设置点击事件时,控制台报错: [Intervention] Unable to preventDefault inside passive event listen ...

  10. 【剑指Offer】【树】二叉搜索树的后序遍历序列

    题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. A:在二叉树的后序遍历中,数组最后一个元素为根节点,左 ...