了解JVM
1:了解JVM是什么东西
做java开发基本都知道,JVM其实就是虚拟机。JVM是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。所以,JAVA虚拟机JVM是属于JRE的,而现在我们安装JDK时也附带安装了JRE(当然也可以单独安装JRE)。
cmd进行控制台输入java -version命令可以看到本机的虚拟机信息。本文主要讲的是HotSpot。
Java EE是以Java SE为基础的。所以并没有“JVM for Java EE”这么一说,只有“JVM for Java SE”,可以用于Java SE与Java EE。
在这个类别下,主流选择有:(按流行程度递减)HotSpot VM J9 VM Zing VM https://blog.csdn.net/lxlmycsdnfree/article/details/69286099
从Java SE 7开始,HotSpot VM就是Java规范的“参考实现”(RI,Reference Implementation)。把它叫做“标准JVM”完全不为过。
当大家说起“Java性能如何如何”、“Java有多少种GC”、“JVM如何调优”等等,经常默认说的就是特指HotSpot VM。可见其“主流性”。
(其实这不是件好事;具体到JVM实现才可以讨论的问题还是应该指明讨论是基于哪个实现)JDK8的HotSpot VM已经是以前的HotSpot VM与JRockit VM的合并版,也就是传说中的“HotRockit”,只是产品里名字还是叫HotSpot VM。这个合并并不是要把JRockit的部分代码插进HotSpot里,而是把前者一些有价值的功能在后者里重新实现一遍。移除PermGen、Java Flight Recorder、jcmd等都属于合并项目的一部分。
不过要留意的是,这里我说的HotSpot VM特指“正常配置”版,而不包括“Zero / Shark”版。Wikipedia那个页面上把后者称为“Zero Port”。用这个版本的人应该相当少,很多时候它的release版都build不成功…
2:JVM的体系结构
3:类加载器
加载class文件~
1.虚拟机自带的加载器
2.启动类(根)加载器
3.应用程序加载器
4.外边扩展加载器
5.双亲委派(安全)机制 https://www.jianshu.com/p/1e4011617650
4:沙箱安全机制
我们都知道,程序员编写一个Java程序,默认的情况下可以访问该机器的任意资源,比如读取,删除一些文件或者网络操作等。当你把程序部署到正式的服务器上,系统管理员要为服务器的安全承担责任,那么他可能不敢确定你的程序会不会访问不该访问的资源,为了消除潜在的安全隐患,他可能有两种办法:
- 让你的程序在一个限定权限的帐号下运行。
- 利用Java的沙箱机制来限定你的程序不能为非作歹。以下用于介绍该机制。
- Java安全模型的核心就是Java沙箱(sandbox),什么是沙箱?沙箱是一个限制程序运行的环境。沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问,那系统资源包括什么?——
CPU、内存、文件系统、网络
。不同级别的沙箱对这些资源访问的限制也可以不一样。 - 所有的Java程序运行都可以指定沙箱,可以定制安全策略。
- https://blog.csdn.net/qq_30336433/article/details/83268945
5:Native,方法区
java的方法bai区在jdk7及以前是永久代,使用的是虚拟机的内存,du而到了zhijdk8,元空间取代了永久代,使用的是本地的内存dao。
Native Method是本地方法的意思,非java编写,比如c/c++,一般用于操作底层的硬件。在java中通过本地方法接口也就是带native修饰符的方法来调用本地方法。
Native https://www.cnblogs.com/KingIceMou/p/7239668.html
方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。
方法区(method area)只是JVM规范中定义的一个概念,用于存储类信息、常量池、静态变量、JIT编译后的代码等数据,具体放在哪里,不同的实现可以放在不同的地方。而永久代是Hotspot虚拟机(常用)的特有的概念,是方法区的一种实现,别的JVM都没有这个东西。
当一个classLoder启动的时候,classLoader的生存地点在jvm中的堆,然后它会去主机硬盘上将A.class装载到jvm的方法区,方法区中的这个字节文件会被虚拟机拿来new A字节码(),然后在堆内存生成了一个A字节码的对象,然后A字节码这个内存文件有两个引用一个指向A的class对象,一个指向加载自己的classLoader。那么方法区中的字节码内存块,除了记录一个class自己的class对象引用和一个加载自己的ClassLoader引用之外,还记录了什么信息呢?
6:栈:数据结构的一种
程序 = 数据结构加算法 。 提升自己
程序 = 框架加业务逻辑。 恰饭用的
栈:先进后出,后进先出。
队列:先进先出。
虚拟机栈:表示Java方法执行的内存模型,每调用一个方法就会为每个方法生成一个栈帧(Stack Frame),用来存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法被调用和完成的过程,都对应一个栈帧从虚拟机栈上入栈和出栈的过程。虚拟机栈的生命周期和线程是相同的。栈不会存在垃圾回收。
栈溢出的错误实例 https://www.cnblogs.com/panxuejun/p/5882424.html
public class Test { public static void main(String[] args) { a(); } public static void a(){ test(); } public static void test(){ a(); } }
Exception in thread "main" java.lang.StackOverflowError at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12) at mydemo.Test.a(Test.java:9) at mydemo.Test.test(Test.java:12)
7.堆
Heap,一个JVM只有一个堆内存,堆内存大小是可以调节的。
类加载器读取文件后一版会把class 方法 常量.....放入堆中。
https://blog.csdn.net/u013728021/article/details/84034420
堆内存中细分为三大区域,
1.新生区(伊甸园区)
类诞生和成长的地方 甚至死亡
所有的对象都是在新生区new出来的
在java中有90%的对象都是临时对象
2.养老区
3.永久储存区
这个区域常驻内存,用来存放JDK自代的类,这个区域不存在垃圾,关闭JVM就会释放这个区域的内存。
JDK1.6之前:永久代,常量池是在方法区
JDK1.7:永久代,但是在慢慢退化,去永久代,常量池在堆中
JDK1.8:无永久代,常量池在元空间。
GC垃圾回收主要是在新生区(伊甸园区)和养老区
假设内容满了,OMM,堆内存不够。在JDK8之后永久储存区改名为元空间。
7.MAT、Jprofiler工具的作用
1.分析Dump内存文件、快速定位内存泄露
2.获得堆中的数据
......................