当前位置: 首页 > news >正文

石家庄手机网站建设软件专利怎么申请

石家庄手机网站建设,软件专利怎么申请,深圳网络推广哪家,一般通过什么渠道了解防灾减灾知识目录 Java内存区域 运行时数据区域 线程独享区域 程序计数器 Java 虚拟机栈 StackFlowErrorOOM 本地方法栈 线程共享区域 堆 GCR-分代回收算法 字符串常量池 方法区 运行时常量池 HotSpot 虚拟机对象探秘 对象的创建 对象的内存布局 句柄 Java内存区域 运…目录 Java内存区域 运行时数据区域 线程独享区域 程序计数器 Java 虚拟机栈 StackFlowErrorOOM 本地方法栈 线程共享区域 堆 GCR-分代回收算法 字符串常量池 方法区 运行时常量池 HotSpot 虚拟机对象探秘 对象的创建 对象的内存布局 句柄 Java内存区域 运行时数据区域 Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。 JDK 1.8 和之前的版本略有不同我们这里以 JDK 1.7 和 JDK 1.8 这两个版本为例介绍。 JDK1.7运行时数据区域 JDK1.8运行时数据区域: Java的运行时区域可以分成两个大的部分一个是所有线程共享的区域一个是当前线程独享的区域。 线程独享的区域 生命周期与线程相同随着线程创建而创建随着线程死亡而死亡 程序计数器相当于一个程序运行的光标标记了程序的运行位置 虚拟机栈使用了栈的存储结构将方法的调用顺序进行记录同时记录了方法的一些信息 本地方法栈 线程共享区域 堆保存数组和对象的位置但是数组其实也是对象 方法区 直接内存除了JVM定义的内存之外运行的主机的运行内存上申请的内存 Java 虚拟机规范对于运行时数据区域的规定是相当宽松的。以堆为例堆可以是连续空间也可以不连续。堆的大小可以固定也可以在运行时按需扩展 。虚拟机实现者可以使用任何垃圾回收算法管理堆甚至完全不进行垃圾收集也是可以的 线程独享区域 程序计数器 是什么 是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成。 有什么用 字节码解释器通过改变程序计数器来依次读取指令从而实现代码的流程控制如顺序执行、选择、循环、异常处理。 在多线程的情况下程序计数器用于记录当前线程执行的位置从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。 注意程序计数器是唯一一个不会出现 OutOfMemoryError 的内存区域它的生命周期随着线程的创建而创建随着线程的结束而死亡。 Java 虚拟机栈 是什么 栈除了一些 Native 方法调用是通过本地方法栈实现的(后面会提到)其他所有的 Java 方法调用都是通过栈来实现的也需要和其他运行时数据区域比如程序计数器配合。 Native方法指的是指使用本地代码实现的方法。这些方法是在Java代码中声明的但实际的实现代码是由非Java语言如C、C或其他语言编写的并且通常在Java虚拟机JVM外部运行。 使用native方法可以提供更高的性能和更低级别的控制因为本地代码可以直接与操作系统和硬件交互。然而这也增加了代码的复杂性和维护难度因为本地代码需要单独编译和测试。 方法调用的数据需要通过栈进行传递每一次方法调用都会有一个对应的栈帧被压入栈中每一个方法调用结束后都会有一个栈帧被弹出。 栈由一个个栈帧组成而每个栈帧中都拥有局部变量表、操作数栈、动态链接、方法返回地址。和数据结构上的栈类似两者都是先进后出的数据结构只支持出栈和入栈两种操作。 局部变量表主要存放了编译期可知的各种数据类型boolean、byte、char、short、int、float、long、double、对象引用reference 类型它不同于对象本身可能是一个指向对象起始地址的引用指针也可能是指向一个代表对象的句柄或其他与此对象相关的位置。 操作数栈主要作为方法调用的中转站使用用于存放方法执行过程中产生的中间计算结果。另外计算过程中产生的临时变量也会放在操作数栈中。 动态链接主要服务一个方法需要调用其他方法的场景。Class 文件的常量池里保存有大量的符号引用比如方法引用的符号引用。当一个方法要调用其他方法需要将常量池中指向方法的符号引用转化为其在内存地址中的直接引用。动态链接的作用就是为了将符号引用转换为调用方法的直接引用这个过程也被称为 动态连接 。 public class Main {public static void main(String[] args) {int i 10;int a i;int b i;}public void a() {System.out.println(aa);b();}public void b() {System.out.println(bbb);} } 通过反编译可以看到方法在常量池都会有一个符号引用 方法A中调用了B方法所以方法A中会有方法B的应用并且这里的引用#5都是和前面的常量池能够对上的 StackFlowErrorOOM 栈空间虽然不是无限的但一般正常调用的情况下是不会出现问题的。不过如果函数调用陷入无限循环的话就会导致栈中被压入太多栈帧而占用太多空间导致栈空间过深。那么当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候就抛出 StackOverFlowError 错误。 Java 方法有两种返回方式一种是 return 语句正常返回一种是抛出异常。不管哪种返回方式都会导致栈帧被弹出。也就是说 栈帧随着方法调用而创建随着方法结束而销毁。无论方法正常完成还是异常完成都算作方法结束。 除了 StackOverFlowError 错误之外栈还可能会出现OutOfMemoryError错误这是因为如果栈的内存大小可以动态扩展 如果虚拟机在动态扩展栈时无法申请到足够的内存空间则抛出OutOfMemoryError异常。 简单总结一下程序运行中栈可能会出现两种错误 StackOverFlowError 若栈的内存大小不允许动态扩展那么当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候就抛出 StackOverFlowError 错误。 OutOfMemoryError 如果栈的内存大小可以动态扩展 如果虚拟机在动态扩展栈时无法申请到足够的内存空间则抛出OutOfMemoryError异常。 本地方法栈 和虚拟机栈所发挥的作用非常相似区别是虚拟机栈为虚拟机执行 Java 方法 也就是字节码服务而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。 本地方法被执行的时候在本地方法栈也会创建一个栈帧用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。 方法执行完毕后相应的栈帧也会出栈并释放内存空间也会出现 StackOverFlowError 和 OutOfMemoryError 两种错误。 线程共享区域 堆 Java 虚拟机所管理的内存中最大的一块Java 堆是所有线程共享的一块内存区域在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例几乎所有的对象实例以及数组都在这里分配内存。 Java 堆是垃圾收集器管理的主要区域因此也被称作 GC 堆Garbage Collected Heap。从垃圾回收的角度由于现在收集器基本都采用分代垃圾收集算法所以 Java 堆还可以细分为新生代和老年代再细致一点有Eden、Survivor、Old 等空间空间的大小比为811。进一步划分的目的是更好地回收内存或者更快地分配内存。 在 JDK 7 版本及 JDK 7 版本之前堆内存被通常分为下面三部分 新生代内存(Young Generation) 老生代(Old Generation) 永久代(Permanent Generation) JDK 8 版本之后 PermGen(永久代) 已被 Metaspace(元空间) 取代元空间使用的是本地内存。 我会在方法区这部分内容详细介绍到。 GCR-分代回收算法 上面的分代也是涉及到了垃圾回收算法中的分代回收算法。 首先所有新创建的对象在一开始都会进入到新生代的Eden区如果是大对象会被直接丢进老年代在进行新生代区域的垃圾回收时首先会对所有新生代区域的对象进行扫描并回收那些不再使用对象 接着在一次垃圾回收之后Eden区域没有被回收的对象会进入到Survivor区。在一开始From和To都是空的而GC之后所有Eden区域存活的对象都会直接被放入到From区最后From和To会发生一次交换也就是说目前存放我们对象的From区变为To区而To区变为From区 接着就是下一次垃圾回收了操作与上面是一样的不过这时由于我们To区域中已经存在对象了所以在Eden区的存活对象复制到From区之后所有To区域中的对象会进行年龄判定每经历一轮GC年龄1如果对象的年龄大于默认值为15那么会直接进入到老年代否则移动到From区 最后像上面一样交换To区和From区之后不断重复以上步骤。 字符串常量池 字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串String 类专门开辟的一块区域主要目的是为了避免字符串的重复创建。字符串常量池从1.7开始就是从方法去移动到了堆中并且静态变量都保存在里面 为什么移到堆中 在JDK 1.7之前字符串常量池存放在方法区中字符串常量在编译时分配在常量池中。然而这种方法存在一些限制例如方法区的大小是固定的如果方法区溢出会导致OutOfMemoryError错误。此外由于方法区的内存分配和回收相对较慢只有FULL GC才会垃圾回收因此可能会影响程序的性能。 HotSpot 虚拟机中字符串常量池的实现是 src/hotspot/share/classfile/stringTable.cpp ,StringTable 可以简单理解为一个固定大小的HashTable 容量为 StringTableSize可以通过 -XX:StringTableSize 参数来设置保存的是字符串key和 字符串对象的引用value的映射关系字符串对象的引用指向堆中的字符串对象。 方法区 当虚拟机要使用一个类时它需要读取并解析 Class 文件获取相关信息再将信息存入到方法区。方法区会存储已被虚拟机加载的 类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。 方法区和永久代以及元空间是什么关系呢 方法区和永久代以及元空间的关系很像 Java 中接口和类的关系类实现了接口这里的类就可以看作是永久代和元空间接口可以看作是方法区也就是说永久代以及元空间是 HotSpot 虚拟机对虚拟机规范中方法区的两种实现方式。并且永久代是 JDK 1.8 之前的方法区实现JDK 1.8 及以后方法区的实现变成了元空间。 为什么要将永久代 (PermGen) 替换为元空间 (MetaSpace) 呢? 1、整个永久代有一个 JVM 本身设置的固定大小上限无法进行调整而元空间使用的是本地内存受本机可用内存的限制虽然元空间仍旧可能溢出但是比原来出现的几率会更小。 当元空间溢出时会得到如下错误java.lang.OutOfMemoryError: MetaSpace 你可以使用 -XXMaxMetaspaceSize 标志设置最大元空间大小默认值为 unlimited这意味着它只受系统内存的限制。-XXMetaspaceSize 调整标志定义元空间的初始大小如果未指定此标志则 Metaspace 将根据运行时的应用程序需求动态地重新调整大小。 2、元空间里面存放的是类的元数据这样加载多少类的元数据就不由 MaxPermSize 控制了, 而由系统的实际可用空间来控制这样能加载的类就更多了。 3、在 JDK8合并 HotSpot 和 JRockit 的代码时, JRockit 从来没有一个叫永久代的东西, 合并之后就没有必要额外的设置这么一个永久代的地方了。 方法区常用参数有哪些 JDK 1.8 之前永久代还没被彻底移除的时候通常通过下面这些参数来调节方法区大小。 -XX:PermSizeN //方法区 (永久代) 初始大小 -XX:MaxPermSizeN //方法区 (永久代) 最大大小,超过这个值将会抛出 OutOfMemoryError 异常:java.lang.OutOfMemoryError: PermGen 相对而言垃圾收集行为在这个区域是比较少出现的但并非数据进入方法区后就“永久存在”了。 JDK 1.8 的时候方法区HotSpot 的永久代被彻底移除了JDK1.7 就已经开始了取而代之是元空间元空间使用的是本地内存。下面是一些常用参数 -XX:MetaspaceSizeN //设置 Metaspace 的初始和最小大小 -XX:MaxMetaspaceSizeN //设置 Metaspace 的最大大小 与永久代很大的不同就是如果不指定大小的话随着更多类的创建虚拟机会耗尽所有可用的系统内存。 运行时常量池 运行时常量池的功能类似于传统编程语言的符号表尽管它包含了比典型符号表更广泛的数据。 既然运行时常量池是方法区的一部分自然受到方法区内存的限制当常量池无法再申请到内存时会抛出 OutOfMemoryError 错误 HotSpot 虚拟机对象探秘 HotSpot虚拟机是Java虚拟机的一种实现它是Sun Microsystems公司开发的一款高性能、动态类型的计算机编程语言虚拟机。HotSpot虚拟机采用了即时编译JIT技术可以将Java字节码转换为本地机器代码从而提高程序的执行效率。 对象的创建 Java 对象的创建过程——五步 检查类是否已经被加载 new关键字时创建对象时首先会去运行时常量池中查找该引用所指向的类有没有被虚拟机加载如果没有被加载那么会进行类的加载过程。加载将class文件读取到内存中使用加载器进行加载 为对象分配内存空间 当类加载检查通过后虚拟机会为新生对象分配内存空间对象所需内存空间的大小在类加载完成后就已经确定了。为新生对象分配内存空间其实就是在Java堆中划分出一块确定大小的内存分配给新生对象。分配内存的方式有“指针碰撞”和“空闲列表”两种选择哪种分配方式取决于Java堆内存是否规整。 内存分配的两种方式 指针碰撞 使用场合堆内存规整即没有内存碎片的情况下。 实现原理将用过的内存都整合到一边没有用过的内存放到另一边中间有一个分界指针当需要为新对象分配内存空间时只需要将分界指针向没有用过的内存一侧移动对象内存大小位置即可。 空闲列表 使用场合堆内存不规整的情况下。JDK8默认的GR垃圾回收方式是不规整的方式 实现原理虚拟机会维护一个列表该列表记录了哪些内存是可用的当需要为新对象分配内存空间时只需要在列表中找一块足够大小的内存分配给对象实例然后更新列表记录。 选择以上两种方式中的哪一种取决于 Java 堆内存是否规整。而 Java 堆内存是否规整取决于 GC 收集器垃圾采用的垃圾收集算法 对象初始化零值 内存分配完成后虚拟机需要将新分配的内存空间都初始化为零值(不包括对象头)这一步操作保证了对象的实例字段可以在Java代码中可以不赋初始值就直接使用程序能够访问这些实例字段的数据类型所对应的零值。 设置对象头 初始化零值之后虚拟机需要对对象头进行必要的设置例如这个对象是哪个类的实例如何才能找到这个类的元数据信息对象的哈希码、GC 分代年龄、锁标志位、偏向锁标志位、线程持有的锁信息、对象是否可用等信息会存放到对象头中。另外根据虚拟机当前运行状态的不同如是否启用偏向锁等对象头会有不同的设置方式。 执行init方法 执行完new指令后会接着执行init方法将对象按照程序员的需求来进行初始化这样一个真正可用的对象才算完全产生出来。 上述为无父类的对象创建过程。对于有父类的对象创建过程还需满足如下条件 先加载父类再加载本类 先执行父类的实例的初始化方法init成员变量、构造代码块父类的构造方法执行本类的实例的初始化方法init成员变量、构造代码块本类的构造方法。 对象的内存布局 在 Hotspot 虚拟机中对象在内存中的布局可以分为 3 块区域对象头、实例数据和对齐填充。 对象头虚拟机的对象头包括两部分信息第一部分用于存储对象自身的运行时数据哈希码、GC 分代年龄、锁状态标志等等另一部分是类型指针即对象指向它的类元数据的指针虚拟机通过这个指针来确定这个对象是哪个类的实例。 实例数据实例数据部分是对象真正存储的有效信息也是在程序中所定义的各种类型的字段内容。 对齐填充仅仅起占位作用方便进行读取和运算 句柄 如果使用句柄的话那么 Java 堆中将会划分出一块内存来作为句柄池reference 中存储的就是对象的句柄地址而句柄中包含了对象实例数据与对象类型数据各自的具体地址信息。 对象的访问定位-使用句柄 如果使用直接指针访问reference 中存储的直接就是对象的地址。 对象的访问定位-直接指针 这两种对象访问方式各有优势。使用句柄来访问的最大好处是 reference 中存储的是稳定的句柄地址在对象被移动时只会改变句柄中的实例数据指针而 reference 本身不需要修改。使用直接指针访问方式最大的好处就是速度快它节省了一次指针定位的时间开销。 参考文章 JavaGuide-JVM内存区域 青空霞光-Jvm内存管理
http://www.pierceye.com/news/142608/

相关文章:

  • 找个免费网站这么难吗做球形全景的网站
  • c语言做网站后端深圳商业网站建设哪家好
  • wordpress小说网站模板下载地址网站建设中企动力推荐
  • 自己做网站网页剧中中国科技
  • 石家庄网站制作福州怎么提升网站打开速度
  • 网站分布郴州建设网站公司
  • 最有效的网站推广费用seo推广是什么意怿
  • 网站推广的基本方法是网站建设公司的介绍
  • 网站开发企业部门网站按抓取手机软件贵阳
  • 龙岗做网站公司icxun临夏州建设网站
  • 网站跳转到另外一个网站怎么做品牌推广部的职责
  • 视频网站开发用什么服务器wordpress数据库邮箱
  • 网站建设公司前十名电子商务网站建设论文开题报告
  • 泉州公司建设网站秦皇岛市网站建设
  • 网站建设说课获奖视频小程序制作用华网天下优惠
  • 杭州网站建设公司代理加盟广东建设企业网站怎么样
  • 网站建制作公司企业营销
  • 建设网站基本流程佛山制作网页公司
  • 眼睛网站开发wordpress影院插件
  • 成都专业做网站的公司有哪些建设工程管理专业
  • 北京seo关键词优化外包网站seo诊断分析报告
  • 怎么做淘宝客网站注册域名后如何建立网站
  • 网络营销资讯网站茶山镇仿做网站
  • 东莞产品网站建设网络设计方案包括哪些
  • 精品课程网站建设论文一个网站如何做推广
  • elementui 做的网站个人网站做推广
  • 外贸 静态网站 怎么做网页制作的目的和意义
  • 做酒店的网站免费进销存软件哪个简单好用
  • 湖州做网站推广的公司phpnow安装wordpress
  • 荆州网站建设销售网站怎么做的