JAVA JVM基础理解(一)

1.Java的内存划分

程序计数器(PC, Program Counter Register)。在JVM规范中,每个线程都有它自己的程序计数器,并且任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址;或者,如果是在执行本地方法,则是未指定值(undefined).(唯一不会抛出OutOfMemoryError)

第二,JAVA虚拟机栈(Java Virtual Machine Stack), 早起也叫Java栈,每个线程在创建时 都会调用一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame), 对应着一次次的Java方法调用。

前面谈程序计数器时,提到了当前方法:同理。在一个时间点,对应的只会有一个活动的栈帧,通常叫当前帧,方法所在的类叫做当前类。如果在该方法中调用了其他方法,对应的新的栈帧会被创建出来,成为新的当前帧,一直到它返回结果或者执行结束。JVM直接对Java栈的操作只有两个,就是栈帧的压栈和出栈。

栈帧中存储着局部变量表、操作数栈、动态链接、方法正常退出或者异常退出的定义等。

第三,堆(Heap), 它是Java内存管理的核心区别,用来放置Java对象实例,几乎所有创建的Java对象实例都是被直接分配在堆上。堆被所有的线程共享,在虚拟机启动时,我们制定的“Xmx”之类参数就是用来制定最大堆空间等指标。

(编译器通过逃逸分析,确定对象是在栈上分配还是在堆上分配)理所当然,堆也是垃圾收集器重点照顾的区域,所以堆内空间还会被不同的垃圾收集器进行进一步的细分,最有名的就是新生代、老年代的划分

第四,方法区(Method Area)。这也是所有线程共享的一块内存区域,用于存储所谓的元(Meta)数据,例如类结构信息,一级对应的运行时常量池、字段、方法代码等。

由于早期的Hotspot JVM实现,很多人习惯将方法区称为永久代 Oracle JDK8中将永久代溢出,同时增加了元数据区

第五、运行时常量池(Run-Time Constant Pool), 这是方法区的一部分。如果仔细分析过反编译的类文件结构,能看到版本号、字段、方法、超累、接口等各种信息,还有一项信息就是常量池。Java的常量池可以存放更重常量信息,不管是编译器生成的各种字面量,还是需要在运行时决定的符号引用,所以它比一般语言的符号表存储的信息更加宽泛。

第六、本地方法栈(Native Method Stack)。它和Java虚拟机栈是非常相似的,支持对本地方法的调用,也是每个线程都会创建一个。在Oracle Hotspot JVM 中,本地方法栈和Java虚拟机栈是在同一块儿区域,这完全取决于技术实现的决定,并未在规范中强制。

2.什么是Java虚拟机?为什么Java被称作是“无关平台的编程语言”?

Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java原文件被编译成被Java虚拟机执行的字节码文件。Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。

3.如何判断一个对象应该被回收?

1)在Java中采取了 可达性分析法

通过一系列的“GC Roots” 对象作为起点进行搜索,“如果在GC Roots” 和一个对象之间没有可达路径,则称该对象是不可达的,不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了

2)虚拟机栈中引用的对象、方法区类静态属性引用的对象、方法去常量池引用的对象、本地方法栈JNI引用的对象

4.GC触发的条件?

1)程序调用System.gc 时可以触发

2)系统自身来决定GC触发的时机

5.可以作为GCRoots的对象有哪些?

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中引用的对象
6、JVM中一次完整的GC流程是怎样的,对象如何晋升到老年代

Java堆 = 老年代 + 新生代

新生代 = Eden + SO + S1

当Eden区的空间满了,Java虚拟机会触发一次 Minor GC , 以收集新生代的垃圾,存活下来的对象,则会转移到Survivor区。

大对象(需要大量连续内存空间的Java对象,如那种很长的字符串),直接进入老年态;

如果对象在Eden出生,并经过第一次Minor GC 后仍然存活,并且被Survivor 容纳的话,年龄设为1,没熬过一次Minor GC,年龄+1,若年龄超过一定限制(15),则被晋升到老年态。即长期存活的对象进入老年态。

老年代满了而无法容纳更多的对象,Minor GC之后通常就会进行Full GC , Full GC 清理整个内存堆-包括年轻代和老年代。

Major GC 发生在老年代的GC,清理老年区,经常会伴随至少一次Minor GC,比Minor GC 慢10倍以上。

7、双亲委派模型

双亲委派模型工作过程是:

如果一个类加载器收到类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器完成。每个类加载器都是如此,只有当父加载器在自己的搜索范围内找不到指定的类时(即ClassNotFoundException),子加载器才会尝试自己去加载。

8、为什么需要双亲委派模型

防止内存中出现多份同样的字节码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值