临近过年,事太多,学习效率也好低,最近已经好久没搞学习了,发篇简单的学习笔记意思下吧
5. 沙箱安全机制
Java安全模型的核心就是Java沙箱(sandbox),什么是沙箱?沙箱是一个限制程序运行的环境。沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问,那系统资源包括什么?——CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不一样。
所有的Java程序运行都可以指定沙箱,可以定制安全策略。
6. Native
凡是带了native 关键字的,说明java的作用范围达不到了,会去调用底层C 语言的库。
凡是带了native 关键字的,会进入本地方法栈。
调用本地接口:JNI
JNI作用:扩展Java的使用,融合不同的编程语言为Java 所用!最初C、C++
它在内存区域中专门开辟了一块标记区域:Native Method Stack,登记native 方法
在最终执行的时候去加载本地方法库的方法,通过JNI
本地方法接口(JNI)Java Native Interface
Native Method Stack(本地方法栈):登记native 方法,在执行引擎(Execution Engine)执行的时候。通过JNI 加载**本地方法库(Native Libraies)**中的方法。在企业级应用中少见,与硬件有关应用:java程序驱动打印机,系统管理生产设备等,掌握即可
CAS源码实现也用到了JNI:https://itcgg.blog.csdn.net/article/details/128668246
private native void start0();
调用其他接口:Scoket 、WebService~http
7. PC寄存器
程序计数器: Program Counter Register:
每个线程都有一个程序计数器,是线程私有的,就是一个指针, 指向方法区中的方法字节码 ( 用来存储指向下一条指令的地址, 也即将要执行的指令代码 ), 在执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计。
8. 方法区
Method Area方法区:
方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单说,所有定义的方法的信息都保存在该区域,此区域属于共享区间;
静态变量、常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区中,但是实例变量存在堆内存中,和方法区无关。
如:static,final,Class(类模板), 常量池
面试题:一张白纸,画出对象实例化过程的内存图。(主要是考你对JVM的理解)
栈,堆,方法区的交互
8.1 方法区概念
Hotspot虚拟机,方法区有个别称non-heap(非堆),方法区可以看作是一块独立于堆的内存空间
- 方法区与java堆一样,是各个线程共享的内存区域
- 方法区在jvm启动的时候被创建,并且它的实际的物理内存空间中和java堆区一样都是可以不连续的
- 方法区的大小,跟堆空间一样,可以选择固定大小或者扩展
- 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误java8以前(java.lang.OutOfMemoryError:PermGen space)或者java8以后(java.lang.OutOfMemoryError:Metaspace)
- 关闭jvm就会释放这个区域的内存
8.2 处理OOM
- OOM或者heap space异常,一般使用内存映像分析工具对dump出来的堆存储快照分析,分析是内存泄漏还是内存溢出
- 如果是内存泄漏,可进一步通过查看GC roots的引用链,查找到泄漏对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收。
- 如果不是内存泄漏,那就是说对象必须存活,此时需要增加虚拟机的参数(-Xmx和-Xms)。
8.3 方法区内部结构
方法区存储信息主要:类型信息,域(Field)信息,方法(Method)信息,常量,静态变量,即时编译器编译后的代码缓存
8.3.1 类型信息
对每个加载的类型(类class、接口、枚举、注解),jvm必须在方法区存储以下类型信息
- 类型的完整有效名称(全名=包名.类名)
- 类型直接父类的完整有效名(接口和java.lang.Object,没有父类)
- 类型的修饰符(public,abstract,final的某个子集)
- 类型直接接口的一个有序列表
8.3.2 域(Field)信息
- 保存类型的所有域的相关信息以及域的声明顺序
- 域的相关信息:域名称,域类型,域修饰符(public,private,protected,static,final,volatile,transient)
8.3.3 方法(Method)信息
jvm保存所有方法的以下信息,同域信息一样的包括声明顺序
- 方法名称
- 方法返回参数(或者void)
- 方法参数的数量和类型(按顺序)
- 方法的修饰符(public,private,protected,static,final,synchronized,native,abstract)
- 方法的字节码,操作数栈、局部变量表及大小(abstract和native除外)
- 异常表(abstract和native除外),每个异常处理的开始位置,结束位置,代码处理在程序计数器中的偏移地址、被捕获的异常类的常量池索引。
8.3.4 常量池
一个有效的字节码文件除了包含类的版本信息,字段,方法以及接口等描述信息外,还包含一项信息那就是常量池,包含各种字面量(数量值,字符串值)和对类型(类),域和方法的符号引用。
常量池,可以看作是一个表,虚拟机指令根据这张常量表找到要执行的类名,方法名,参数类型,字面量等类型
作用
一个java源文件的类,接口,编译后产生一个字节码文件。而java中字节码需要数据支持,通常这种数据会很大以至于不能直接存储在字节码里,换一种方式,可以存储到常量池里。
8.3.5 方法区的垃圾回收
方法区的回收效果不好,尤其是对类型的卸载,条件很苛刻,但是回收方法区又是必要的。
- 方法区的垃圾回收主要回收两部分
- 常量池中废弃的常量
- 不再使用的类型,需要将其卸载
- 判定一个类型是否能被卸载的条件
- 该类所有的实例都已经被回收,java堆中不存在该类以及任何派生子类的实例
- 加载该类的加载器已经被回收。
- 该类对应的java.lang.Class对象没有任何地方被引用,没有任何地方通过反射访问该类的方法