【读书笔记】JAVA基础:1、深入理解JVM
发布日期:2021-06-24 15:29:05 浏览次数:2 分类:技术文章

本文共 3190 字,大约阅读时间需要 10 分钟。

 

通过《深入理解JAVA虚拟机》和《深入理解计算机系统》两本经典著作的学习,注重了解系统进程运行时内存结构的变化,以此彻底了解JVM虚拟机在运行JAVA程序时的内存结构!

 

 

 

主要有三个方面:

        1、计算机系统的内部系统结构;

        2、JVM运行时数据内存结构;

        3、通过简单的JAVA程序彻底理解JVM执行流程。

 

 

 

一、计算机系统的内部系统结构

        先看一张图,有个大体印象:

 

首先,要记住的是,一系列语言的的源文件保存在磁盘上,通过解释器解释后成可执行文件,也保存在磁盘上。

下面举个简单的例子,下面有一段简单的C程序,保存为hello.c:

#include 
int main(){ printf("hello,world!"); return 0;}

C语言程序的设计是用来实现Unix操作系统的,那么就可以直接在linux的shell指令进行编译:

[root@localhost lgy] gcc -o hello hello.c

上面命令的意思就是通过GCC编译器将hello.c源文件编程成文件名为hello的可执行文件。

[root@localhost lgy] ./hello

上面命令回车后,发生了下面的流程:

1、通过指令将hello文件中的代码和数据复制到了主存

2、当处理器发现执行文件加载到了主存后,就处理器就会执行主存代码中的main程序,将主存的main程序中的字节复制到了处理器的寄存器中(如果代码中涉及到数据的运算,就会拷贝数据到算术/逻辑单元,计算完之后就会将数据返回寄存器)

3、寄存器执行完命令之后再将数据复制到界面。

这里,我们又会发现一个问题,就是简单的一个程序处理,涉及到了多次的复制,特别是在处理器与主存之间,当我们的程序中设计到函数的调用,结果再次返回主存,下次我们获取还得从主存复制到寄存器,就这影响了性能,这就出现了高速缓存。

高速缓存被设计在处理器中的一个部件,假如我们用的多核处理器,那么就意味着每核处理器里面都包含了寄存器、算术单元、高速缓存等组件。

            以上就是计算机系统执行一个可执行文件的整个流程,对于我们Java攻城狮来说,对其有个大概的了解就可以了,其中具体的指令操作,内存分配等,不是那么重要,当然兴趣是最好的老师,下面的JVM才是我们必须彻底了解的一块。

 

二、JVM运行时数据内存结构;

通过一张JVM运行时内存结构图,有个大致的印象:

JVM运行时内存主要分有五块区域:

堆,方法区---------------------线程共享区域

虚拟机栈、本地方法栈、(直接内存)-------------------线程私有区域

简单分解概念:

程序计数器:是一块很小的内存空间,可以看作当前线程所执行的字节码位置指示灯。这里只需要知道,程序中所出现的分支、循环、跳转(方法调用)、异常处理、线程恢复等基础功能都依赖它。如图,可以看到它在支配着两个栈的计数,如果线程中执行一个Java方法,计数器就会记录正在执行的字节码指令的位置,若是执行的Native方法,计数器的值就是空的。

虚拟机栈:生命周期同线程。每个方法在执行的时候都会创建一个栈帧用来存储局部变量表、操作数栈、动态链接、方法出口等信息。其中,局部变量表存放的是编译器可知的基本数据类型,有int,short,byte,long,float,char,boolean,double,还有对象引用的类型。

本地方法栈:顾名思义,就是Java程序内部调用Native属性的方法所占用的内存空间。

Java堆:很显然,栈中存放的是对象的引用,堆里就存放了对象实例本身(作为了解,有些编译器也不是这么绝对)。堆中重点需要了解的是GC垃圾回收机制。

方法区:主要用于存储已被虚拟机加载过的类信息、常量、静态变量、即时编译器编译后的代码等数据。这个区域也被垃圾回收机制成为持久代,主要是对常量池中数据的回收和对类的卸载。

            方法区中需要了解的是常量池,例如,public String s = "abc",那么“abc”和其符号引用就保存在常量池

直接内存:主要用于NIO,可以使用Native函数库直接分配堆外内存,存放这Java堆中的DirectByteBuffer对象的引用。

 

建议推荐https://blog.csdn.net/fuzhongmin05/article/details/78169044

概念的东西都讲完了,下面的就是重点了。

三、通过简单的JAVA程序彻底理解JVM执行流程。

一个Person类:

public class Person {		private String name;		private static String stat = "0";		private static final int index = 1;		public void work(){		String address = "renminlu";		int day = 0;		while(day < 365){			day ++ ;		}		System.err.println(address);	}		public static void main(String[] args) {		Person person = new Person();		person.work();		assert args.length < 0;		Integer i = 122;		Integer j = 122;		System.err.println(i == j);	}	}

在这个类里面我们定义了一个普通属性name,一个静态属性stat并初始化“0”,一个static final修饰的属性index。

整个程序编译的过程如下图(网上摘抄):

主要看其运行时数据的内存分配:

打开Person所在目录,执行:

javac Person.java
javap -v -c -l Person

 

 

 

 

 

最后汇总一下JVM常见配置

  1. 堆设置
    • -Xms:初始堆大小
    • -Xmx:最大堆大小
    • -XX:NewSize=n:设置年轻代大小
    • -XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
    • -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
    • -XX:MaxPermSize=n:设置持久代大小
  2. 收集器设置
    • -XX:+UseSerialGC:设置串行收集器
    • -XX:+UseParallelGC:设置并行收集器
    • -XX:+UseParalledlOldGC:设置并行年老代收集器
    • -XX:+UseConcMarkSweepGC:设置并发收集器
  3. 垃圾回收统计信息
    • -XX:+PrintGC
    • -XX:+PrintGCDetails
    • -XX:+PrintGCTimeStamps
    • -Xloggc:filename
  4. 并行收集器设置
    • -XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
    • -XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
    • -XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
  5. 并发收集器设置
    • -XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。
    • -XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

 

 

 

 

 

 

 

转载地址:https://blog.csdn.net/weixin_33602978/article/details/79733191 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【开发笔记】茶余饭后:1、CAT监控搭建部署(windows)
下一篇:【开发笔记】茶余饭后:2、Java问题排查(压力测试性能监控)

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月14日 01时46分38秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

【人生杂谈】 - 金钱/名利 & 贫穷/富贵 && 健身房定律 2021-07-01
【人生杂谈】宇宙/暗物质/擎天柱 2021-07-01
【人生杂谈】生命DNA/理性思维/天才&神经病 2021-07-01
Intel 64/x86_64/IA-32/x86处理器段寄存器 - 32位段寄存器/64位段寄存器 2021-07-01
Intel 64/x86_64/IA-32/x86处理器 - 通用指令(1) - 数据传输指令 2021-07-01
Intel 64/x86_64/IA-32/x86处理器 - 通用指令(2) - 二进制算术指令/十进制算术指令 2021-07-01
Intel 64/x86_64/IA-32/x86处理器 - 通用指令(3) - 逻辑指令/移位指令 2021-07-01
【英语学习】【Daily English】U02 Daily Routine L04 It's your turn to do the chores 2019-04-28
【英语学习】【WOTD】prestigious 释义/词源/示例 2019-04-28
【英语学习】【WOTD】emote 释义/词源/示例 2019-04-28
【英语学习】【WOTD】obsequious 释义/词源/示例 2019-04-28
【英语学习】【Daily English】U03 Leisure Time L01 Did you have a nice weekend? 2019-04-28
【英语学习】【WOTD】minion 释义/词源/示例 2019-04-28
【英语学习】【WOTD】sentient 释义/词源/示例 2019-04-28
【网络】SSH本地/远程/动态端口转发 2019-04-28
【英语学习】【WOTD】two-bit 释义/词源/示例 2019-04-28
【英语学习】【WOTD】encroach 释义/词源/示例 2019-04-28
【英语学习】【Daily English】U07 Restaurant L03 What do you recommend? 2019-04-28
【英语学习】【WOTD】smithereens 释义/词源/示例 2019-04-28
【英语学习】【WOTD】parabolic 释义/词源/示例 2019-04-28