1.像windows/linux这种操作系统中,自带jvm么?以方便java程序的运行?

答:是的,一般操作系统都自带jvm的。但不带jdk,也就是说java的运行环境有,但编译环境没有。

1.java程序运行时分哪几种内存区域?

答:大概分为5种内存区域。这5种内存区域,又分为共享区内存,线程私有内存区。

方法区,堆,线程栈,本地方法区,程序计数器。

共享区:堆,方法区。

线程私有区:本地方法区,程序计数器,线程栈。

2.java虚拟机内存划分不同区域的目的什么?

答:为了提高运算效率,就对数据进行了不同空间的划分,每一片区域采用特定的处理数据方式和内存管理方式。

3.java虚拟机都包括哪些知识点?

答:从虚拟机启动开始算起考虑嘛,包括类加载机制,内存分配(内存模型),垃圾回收。

所以,java虚拟机就包括三方面知识点,类加载机制,内存分配和垃圾回收。

2.每种内存区域里存储什么数据?

各区介绍:

  1)方法区(线程共享):用于存放被虚拟机加载的类的信息(就是类的全部代码),静态变量,常量。

  2)Java堆(线程共享):存放对象实例和数组,这里是内存回收的主要地方。可以分为新生代(young)和年老代(tenured)。从字面也可以知道,新生代存放刚刚建立的对象,而年老代存放长久没有被垃圾回收机制回收的对象。一般新生代有分为eden,from survivor和to survivor。这是和回收算法相关的分配(通过-Xms和-Xmx来配置)。

  3)线程栈(线程私有):随线程一起建立,是方法执行的内存模型。当方法开始执行时,载入局部变量(引用变量),参数,返回值。栈的大小决定了方法调用的可达深度(递归多少层次,或嵌套调用多少层其他方法,-Xss参数可以设置虚拟机栈大小)。栈的大小可以是固定的,或者是动态扩展的。如果请求的栈深度大于最大可用深度,则抛出stackOverflowError;如果栈是可动态扩展的,但没有内存空间支持扩展,则抛出OutofMemoryError。

  4)程序计数器(线程私有):java被编译成class,并被JVM解释执行,执行的是每一条指令。程序计数器记录当前线程执行的字节码地址,使得程序在轮询获取CPU时间片执行的时候能够知道从何处执行。因此很好想到,这篇区域是线程私有的,因为这里记录的就是不同线程的执行地址。(程序计数器一般都比较小,所以在内存资源的分析时都会忽略这片内存的占用)。

  5)本地方法栈(线程私有):本地方法栈和虚拟机栈类似,只是这是存储本地方法的内存模型,管理本地方法的执行(Native)

3.java 堆和栈之间是怎样联系的?

答:new创建对象时,是在堆和栈中都分配内存的。Java中对象的存储空间都是在堆中分配的,但是这对象的引用却是在栈中分配,也就是说在建立一个对象时在堆和栈中都分配内存,在堆中分配的内存实际存放这个被创建的对象的本身,而在栈中分配的内存只是存放指向这个堆对象的引用而已。

4.方法退出时,怎么样处理栈内存和堆内存?

答:方法退出时,栈空间立刻被回收,局部变量生命周期立即,堆空间中的刚才方法中创建的对象等待GC回收。

5.栈内存是什么时候建立的?

答:程序是由main()方法开始执行的,java程序总是最少两个线程,main()线程和gc垃圾回收线程。所以main线程是立即建立的,同时立即创建main线程的栈内存。

6.堆,栈,方法区的创建时间是在什么时候创建的?

答:虚拟机启动时自动创建堆。

方法区在被虚拟机加载类的时候,载入类信息、常量、静态常量。

栈是在线程启动时候自动创建。

7.java虚拟机主要包括哪些知识点?

答:Java虚拟机知识点包括内存模型和垃圾回收器。

8.方法区是由什么组成的?

答:方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

9.线程内存是怎样与主内存交互的?

答:当线程与内存区域进行交互时,数据从主存拷贝到工作内存,进而交由线程处理(操作码+操作数)。

Java 虚拟机规范的规定,Java 堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。

10.线程栈的具体组成是?

答:虚拟机栈描述的是Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame ①)用于存储局部变量表、操作栈、动态

链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不等同于对象本身。

栈区:  
1.每个线程包含一个栈区,栈中只保存基础数据类型本身和自定义对象的引用; 
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问; 
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令);

3、 JVM的进程中,每个线程都会拥有一个方法调用栈,用来跟踪线程运行中一系列的方法调用过程,栈中的每一个元素就被称为栈帧,每当线程调用一个方法的时候就会向方法栈压入一个新帧。这里的帧用来存储方法的参数、局部变量和运算过程中的临时数据。

11.java虚拟机垃圾回收机制

12.程序运行时内存分配情况分析

答:首先 启动一个Java虚拟机进程,这个进程首先从classpath中找到AppMain.class文件,读取这个文件中的二进制数据,然后把Appmain类的类信息存放到运行时数据区的 方法区 中,这就是AppMain类的加载过程。

接着,Java虚拟机定位到方法区中AppMain类的Main()方法的字节码,开始执行它的指令。这个main()方法的第一条语句就是:

Sample test1=new Sample("测试1");
该语句的执行过程: 
    1、 Java虚拟机到方法区找到Sample类的类型信息,没有找到,因为Sample类还没有加载到方法区(这里可以看出,java中的内部类是单独存在的,而且刚开始的时候不会跟随包含类一起被加载,等到要用的时候才被加载)。
Java虚拟机立马加载Sample类,把Sample类的类型信息存放在方法区里。  
  2、 Java虚拟机首先在堆区中为一个新的Sample实例分配内存, 并在Sample实例的内存中存放一个方法区中存放Sample类的类型信息的内存地址。 
  3、位于“=”前的Test1是一个在main()方法中定义的一个变量(一个Sample对象的引用),因此,它被会添加到了执行main()方法的主线程的JAVA方法调用栈中。
而“=”将把这个test1变量指向堆区中的Sample实例。 
4、JVM依次执行它们的printName()方法。当JAVA虚拟机执行test1.printName()方法时,JAVA虚拟机根据局部变量test1持有的引用,定位到堆区中的Sample实例,再根据Sample实例持有的引用,
定位到方法去中Sample类的类型信息,从而获得printName()方法的字节码,接着执行printName()方法包含的指令,开始执行。
AppMain.java
 
  public class AppMain //运行时, jvm 把appmain的代码全部都放入方法区
  {
  public static void main(String[] args) //main 方法本身放入方法区。
  {
  Sample test1 = new Sample( " 测试1 " ); //test1是引用,所以放到栈区里, Sample是自定义对象应该放到堆里面
  Sample test2 = new Sample( " 测试2 " );
  
  test1.printName();
  test2.printName();
  }
  }
  
  public class Sample //运行时, jvm 把appmain的信息都放入方法区
  {
  /** 范例名称 */
  private String name; //new Sample实例后, name 引用放入栈区里, name 对应的 String 对象放入堆里
  
  /** 构造方法 */
  public Sample(String name)
  {
  this .name = name;
  }
  
  /** 输出 */
  public void printName() //在没有对象的时候,print方法跟随sample类被放入方法区里。
  {
  System.out.println(name);
  }
  }
13.在Java语言里堆(heap)和栈(stack)里的区别 :

1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。  
2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享(详见下面的介绍)。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

Java中的2种数据类型:

一种是 基本类型 (primitive types), 共有8类,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的,称为自动变量。 自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在 。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。 这些 字面值 的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存 在于栈中 。

栈有一个很重要的特性:存在栈中的数据可以共享。 假设我们同时定义:  int a = 3; int b = 3;   编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,如果没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。

这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与 b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

另一种是 包装类数据, 如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部 存在于堆中, Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。

15.字面变量的引用和类变量引用有什么区别?

答:8种基本类型的引用变量叫字面变量引用,8种基本数据类型是存储在栈中的,不是堆中,因为字面变量的大小是已知的,且生命周期是已知的。int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。栈有一个很重要的特性--栈的数据是可以共享的。说的就是字面变量内容是可以共享的。

假设我们同时定义:  int a = 3; int b = 3;   编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,如果没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。

这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与 b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在 。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。 这些 字面值 的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存 在于栈中 。

16.程序中new创建的对象为什么在程序运行后才根据new命令在堆中创建内存空间?

答:因为new创建的对象是程序猿写的,大小未知啊。所以编译时期不能创建内存空间,程序实际运行时,才知道啊。new创建的对象不像int这种基本数据类型,在编译时期就知道大小,就可以存储在栈中。

15.java的内存分配条理清楚么?

答: java内存分配条理还是很清楚的,如果要彻底搞懂,可以去查阅JVM相关的书籍。

在java中,内存分配最让人头疼的是String对象,由于其特殊性,所以很多程序员容易搞混淆。

java内存模型知识点汇总的更多相关文章

  1. Java内存模型知识点小结---《深入理解Java内存模型》(程晓明)读书总结

    一.Java内存模型介绍 内存模型的作用范围: 在Java中,所有实例域.静态域和数组元素存放在堆内存中,线程之间共享,下文称之为“共享变量”.局部变量.方法参数.异常处理器等不会在线程之间共享,不存 ...

  2. 知识点:Java 内存模型完全解密

    Java虚拟机(JVM) 规范中定义了一种Java的内存模型,即Java Memoory Model(简称JMM),用来实现让Java程序在各个平台下都能达到一致的内存访问效果. JVM是整个虚拟机, ...

  3. JVM学习(3)——总结Java内存模型

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简 ...

  4. 【JVM】JVM内存结构 VS Java内存模型 VS Java对象模型

    原文:JVM内存结构 VS Java内存模型 VS Java对象模型 Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点.而且很多概念的名称看起来又那么相似,很多人会傻傻分不清 ...

  5. java内存模型(转)

    前提知识: Java内存模型(JMM)是一个概念模型,底层是计算机的寄存器.缓存内存.主内存和CPU等.  多处理器环境下,共享数据的交互硬件设备之间的关系: JMM: 从以上两张图中,谈一谈以下几个 ...

  6. 【转】JVM内存结构 VS Java内存模型 VS Java对象模型

    JVM内存结构 我们都知道,Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途. 其中有些区域随着虚拟机进程的启动而 ...

  7. 来,了解一下Java内存模型(JMM)

    网上有很多关于Java内存模型的文章,在<深入理解Java虚拟机>和<Java并发编程的艺术>等书中也都有关于这个知识点的介绍.但是,很多人读完之后还是搞不清楚,甚至有的人说自 ...

  8. JVM学习(3)——总结Java内存模型---转载自http://www.cnblogs.com/kubixuesheng/p/5202556.html

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简 ...

  9. 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则

    前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中.在一次学习中去理解这些东西.才能更好的理解 Jav ...

随机推荐

  1. COLLATE CHINESE_PRC_CI_AS_WS 的含义

    排序规则:COLLATE CHINESE_PRC_CI_AS_WS 的含义 在创建数据表时,常会用到这个. 含义当中,CHINESE_prc_ 是代表中国大陆.如果是台湾,则如:Chinese_TAI ...

  2. Django render函数

    render() 此方法的作用---结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象. 通俗的讲就是把context的内容, 加载进templates中定义 ...

  3. PHP array_key_exists() 函数(判断某个数组中是否存在指定的 key)

    定义和用法 array_key_exists() 函数判断某个数组中是否存在指定的 key,如果该 key 存在,则返回 true,否则返回 false. 语法 array_key_exists(ke ...

  4. 【51nod】1742 开心的小Q

    题解 我们由于莫比乌斯函数如果有平方数因子就是0,那么我们可以列出这样的式子 \(\sum_{i = 1}^{n} \sum_{d|i} (1 - |\mu(d)|)\) 然后枚举倍数 \(\sum_ ...

  5. USACO 6.5 Checker Challenge

    Checker Challenge Examine the 6x6 checkerboard below and note that the six checkers are arranged on ...

  6. codeforces 286 E. Ladies' Shop (FFT)

    E. Ladies' Shop time limit per test 8 seconds memory limit per test 256 megabytes input standard inp ...

  7. flex布局防止被挤压 flex-shrink: 0

    lex布局非常好用,但在开发过程中可能会碰到的一些坑 1.内容超出容器大致情况是:在一个设置了display:flex布局的大容器A中并排放置两个子容器,并且子容器设置flex:1,子容器中都有一个元 ...

  8. ionic启动App时不使用淡入淡出效果

    找到我们项目下面 res下面的config.xml,然后加入下面两句就可以解决. <preference name="FadeSplashScreen" value=&quo ...

  9. 【工具】获取pojo类属性,并写入表格

    1.添加依赖 <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <g ...

  10. 通过GeneXus如何快速构建微服务架构

    概览 “微服务”是一个非常广泛的话题,在过去几年里,市面上存在着各种不同的定义. 虽然对这种架构方式没有一个非常精确的定义,但仍然有一些概念具有代表性. 微服务有着许多围绕业务能力.自动化部署.终端智 ...