深入理解java虚拟机|心得

  • 本人是做java开发有些时日,不安于现状,想研究源码,于是请教行业的一些前辈,建议我读inside
    jvm,于是就有了今天的深入理解java虚拟机这篇博客。 从网上下载的(深入理解Java虚拟机_JVM高级特性与最佳实践
    第2版_220

    (大佬写的不错,Mark一下)https://blog.csdn.net/hupoling/article/details/62887251

2019.01.12|第一章:走进Java

1.1.1 Java程序设计语言、Java虚拟机、Java API类库这三部分统称为JDK(Java Development
Kit),JDK是用于支持Java开发的最小环境。
1.1.2. JDK和JRE所覆盖的范围

1.1. 3. Java技术体系可以分为4个平台,分别是: Java Crad:支持一些小程序,运行在小内存设备的一些平台上。 Java
ME:支持java设备运行在移动终端(手机),前身是J2ME. Java SE:支持面向桌面级的应用,前身是J2SE.
Java EE:支持多层架构的企业级应用(ERP、CRM应用),前身J2EE.
1.1. 4. Java的发展史
在这里插入图片描述

1**.1. 5. 可以运行在JVM上的语言**
**

2019-01-13|第二章:自动内存管理机制

**
2.1java虚拟机在执行java程序中会划分为若干个不同的数据区域。(方法区、虚拟机栈、本地方法栈、堆、程序计数器)

2.1.1程序计数器
占内存空间比较小,字节码解释器工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程回复等基础功能。
一个处理器在任何一个确定的时刻,都只会执行一条线程中的指令。
线程私有:每条线程都需要有一个独立的程序计数器,线程之间互不影响,独立存储。
线程—>Java方法,计数器记录的是正在执行的虚拟机字节码指令的地址。
–>Native方法,计数器值则为空,此区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryaError情况的区域。
2.1.2Java虚拟机栈
是线程私有的,生命周期和线程相同,描述的是Java方法的内存模型
栈—>虚拟机中局部变量表(存放基本数据类型),其中long和double会占用2个局部变量空间,其余数据类型占用1个。
如果线程请求的栈深度>虚拟机所允许的深度,抛出StackOverflowError异常。
如果虚拟机可以动态扩展,扩展到无法申请到足够的内存,就会抛出OutOfMemoryError异常。
2.1.3.本地方法栈
和虚拟机栈发挥的作用类似,区别是:虚拟机栈执行Java方法,本地方法栈执行Native方法。
因为没有强制规定,虚拟机可以自由实现,有的虚拟机直接就把本地方法栈和虚拟机栈合二为一。
2.1.4.Java堆
Java堆所管理的内存是最大的一块,是被所有线程共享的一块内存区域,此区域唯一目的:存放对象实例,很多时候也被称为GC堆,(还好不是垃圾堆),还可细分为:新生代和老年代,
2.1.5.方法区
和Java堆一样,是各个线程共享 的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量即时编译器编译后的代码等数据。还有一个别名叫做Non-Heap(非堆),目的是与Java堆区分开来。
2.1.6.运行时的常量池
方法区的一部分。
。。。
2.1.7直接内存
。。。
2.2hotspot虚拟机对象(如何创建、如何布局以及如何访问)
2.2.1对象的创建
创建对象:new关键字。
虚拟机遇到一条new指令时,首先去检查这个指令的参数是否在常量池中定位到一个类的符号引用,并检查是否被加载、解析和初始化。如果没有,必须先执行相应的类加载过程。
类加载完之后,虚拟机将为新生对象分配内存,对象所需内存的大小在类加载完成后就可以确定。
2.2.2对象的内存布局
在这里插入图片描述
分为3块区域:对象头、实例数据和对齐填充。
对象头:①存储对象自身的运行时数据。②类型指针,对象指向它的类元数据的指针。
2.2.3对象的访问定位

建立对象是为了使用对象,目前访问的方式有两种:句柄和直接指针。
句柄:java堆会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址。(存储稳定)在这里插入图片描述
在这里插入图片描述 直接指针:java堆对象的布局就必须考虑如何放置访问类型数据的相关信息,而reference中存放的直接就是对象地址。(速度快)
2.3OutOfMemOryError异常
2.3.1Java堆溢出
不断创建对象,对象数量达到最大堆的容量限制后就会产生内存溢出。
确认内存中的对象是必要的,分清楚是出现了内存泄漏还是内存溢出。
内存泄漏:通过工具查看泄漏对象到GC Roots的引用链,
如果不是内存泄漏,就是内存中的对象确实都还必须存活着。
2.3.2虚拟机栈和本地方法栈溢出
HotSpot虚拟机中并不区分虚拟机栈和本地方法栈,
。。。
2.3.3方法区和运行时常量池溢出
String.intern()是一个Native方法,作用是:如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象,否则,将此String对象包含的字符串添加到常量池中,并且返回String对象的引用。
。。。
2.3.4被你就直接内存溢出
。。。
**

2019-01-13|第三章:垃圾收集与内存分配策略

3.1GC的由来:
需要排查各种内存溢出、内存泄漏这种情况。
3.2对象已经死了吗
垃圾收集器在对堆进行回收时,会判断哪些对象或者,哪些对象已经死了(不能被使用的对象)
3.2.1引用计数算法
判断对象是否存活的算法:给对象添加一个引用计数器,每当有引用的时候,计数器+1;当引用失效时,计数器-1;任何时刻计数器为0的时候就说明对象时不在被使用的。(Java虚拟机中没有选用计数器来管理内存,是因为它很难解决对象之间循环引用的问题。)
3.2.2在谈引用
JDK1.2之后,将引用分为4种,强、软、弱、虚引用。
强引用:只要引用还存在,垃圾收集器就不会被回收。
软引用:在系统将要发生内存泄漏之前,将会把这些对象列进回收对象进行回收范围内进行二次回收。
弱引用:无论当前内存是否足够,都会回收被弱引用关联的对象。
虚引用:能在这个对象被回收时收到一个系统通知。
3.2.3生存还是死亡
宣告一个对象死亡时,需要进行两次标记过程,
**

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值