JAVA基础笔记2(JVM沙箱安全机制,Native关键字,PC寄存器,方法区,栈)

JAVA基础笔记2

JAVA沙箱安全机制

java安全模型的核心就是java沙箱(sandbox),什么是沙箱?沙箱是一个限制程序运行环境。沙箱机制就是将java代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问系统资源访问包括:CPU,内存,文件系统,网络。不同级别的沙箱对这些资源访问的限制也可以不一样。
所有的java程序运行都可以指定沙箱,可以定制安全策略。
在java中将执行程序分成本地代码和远程代码两种,本地代码默认视为可信任的,而远程代码则被看做是不受信任的。对于授信的本地代码,可以访问一切本地资源。而对于非授信的远程代码在早期的java实现中,安全依赖于沙箱(Sandbox)机制,如下图所示JDK1.0版本安全模型。
在这里插入图片描述
但如此严格的安全机制也给程序的功能扩展带来保障,比如当用户希望远程代码访问本地系统的文件时候,就无法实现。因此在后续的java1.1版本中针对安全机制做了改进,增加了安全策略,允许用户指定代码对本地资源的访问权限。入下图JDK1.1安全模型。
在这里插入图片描述
在java1.2版本中,再次改进了安全机制,增加了代码签名。不管本地代码或是远程代码都会安照用户的安全策略设定,有类加载器加载到虚拟机中权限不同的运行空间,来实现差异化的代码执行权限控制。如下图JDK1.2安全模型。
在这里插入图片描述
当前最新的安全机制实现,则引入了域(Domain)的概念。虚拟机会把所有代码加载到不同的系统域和应用域,系统域部分专门负责与关键资源进行交互,而各个应用域部分则通过系统系统域的部分代理来对各种需要的资源进行访问。虚拟机中不同的受保护域(Protected Domain),对应不一样的权限存在不同域中的类文件就具有了当前域的全部权限,如下图所示,最新安全模型(JDK1.6)。
在这里插入图片描述
沙箱基本组件
字节码校验器(Bytecode verifier):确保java文件遵循java语言规范。这样可以帮助java程序实现内存保护。但并不是所有的类文件都会经过字节码校验,比如核心类。(编译java文件的时候会提示你哪里报错了,什么异常)。
类装载器(Class Loader):其中类装载器在3个方面对java沙箱起作用。

  1. 它防止恶意代码去干涉善意代码双亲委派机制
  2. 它守护了被信任的类库边界。双亲委派机制
  3. 它将代码归入了保护域,确定了代码可以进行哪些操作。java沙箱

虚拟机为不同的类加载器的类提供了不同的命名空间,命名空间由唯一的名称组成,每一个被装载的类将有一个名字,这个命名空间是由java虚拟机为每一个类装载器维护的,它们相互之间甚至不可见。
类装载器采用的机制是双亲委派机制。

  • 从内存JVM自带的类加载器开始加载,外层恶意同名类得不到加载从而无法使用。
  • 由于严格通过包来区分了访问域,外层恶意的类通过内置代码也无法获得权限访问到内层类,破坏代码就自然无法生效。

存取控制器(access controller):存取控制器可以控制核心API对操作系统的存取权限,而这个控制的策略设定可以由用户指定。(有一个机器类,写外挂用的可以控制键盘和鼠标的使用)。
安全管理器(security package):是核心API和操作系统之间的主要接口。实现权限控制,比存取控制器优先级高。
安全软件包(security package):java.security下的类和扩展包下的类,允许用户为自己的应用增加新的安全特性。
包括:

  • 安全提供者
  • 消息摘要
  • 数字签名 Keytools
  • 加密
  • 鉴别

Native

点start()方法进入Thread类里面看源码

public static void main(String[] args){
	new Thread((
		
	) ->{},name:"my thread name").start()
}

看start()这个方法调用了一个接口

private native void start();

为什么类里面能写接口呢?就是因为native这个关键字。

  • native:凡是带了native关键字的,说明java的作用范围达不到了,会去调用底层C语言的库。
  • 会进入本地方法栈。
  • 调用本地方法本地接口 JNI
  • JNI作用:扩展java的使用,融合不同的编程语言为java所用。最初:C,C++。
  • java诞生的时候C,C++横行,想要立足必须要有调用C,C++的程序。
  • 它在内存区域中专门开辟了一块标记区域:Native Method Stack(本地方法栈),登记native方法。
  • 在最终执行的时候,加载本地方法库中的方法 通过JNI。
  • 调用其它接口:Socket,WebService,http等。

PC寄存器

程序计数器:Program Counter Register
每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向一条指令的地址,也即将要执行的指令代码),在执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计。
在这里插入图片描述

方法区

Method Area 方法区
方法区是被所有线程共享的,所有字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单说,所有定义的方法信息都保存在该区域,此区域属于共享区域
静态变量,常量,类信息(构造方法,接口定义),运行时的常量池存放在方法区中,但是实例存在堆内存在,和方法区无关。
存放:static ,final ,Class , 常量池。

栈内存是给线程使用的,每个线程都有自己的线程区域,堆内存放对象的实例可以给进程中的全部线程共享
如果两个方法一直在互相调用,那么就会一直往栈里面重复的存入方法,但是栈是有内存的是会满的,当栈的内存被堆满了之后就会报一个错误:StackOverflowErroe(栈内存溢出错误,无法处理)。

  • 栈:先进后出,后进先出:栈就像跟桶一样
  • 队列:先进先出,后进后出(FIFO : First Input First Output)
  • 喝多了吐就是栈,吃多了拉就是队列
  • 为什么main()先执行,最后结束:因为栈是先进的方法先执行,然后后面进来的方法就会把先进去的方法压在底部,底部的方法想要结束出去,就必须等上面的方法执行完后栈给它弹出去。
  • 栈:栈内存,主管程序的运行,生命周期和线程同步。
  • 线程结束,栈内存也就释放,对于栈来说不存在垃圾回收问题
  • 一旦线程结束,栈就Over。
  • 栈的存放内容:栈是跟着线程的创建而出现的,生命周期跟线程同步,每一个栈中有着栈帧,栈帧对应的就是方法,栈帧中保存了方法内的:基本数据类型,成员变量,对象的引用地址,方法的返回地址。
  • 对象的引用地址指向的就是堆中对象的实例,通过对象的引用地址来获得堆中对象的实例,从而找到实例的方法。
    栈的内存图

栈的内存跟运行原理

  • 栈运行原理:栈帧。
  • 栈内存满了:StackOverflowError 错误。

在这里插入图片描述

栈+堆+方法区直接的关系:class类被实例化的过程如下图。

类被实例化的过程图

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值