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

创建网站基本流程哪家企业网页制作好

创建网站基本流程,哪家企业网页制作好,做一个网站多长时间,网站开发用什么电脑4.堆 堆 一个Java程序#xff08;main方法#xff09;对应一个jvm实例#xff0c;一个jvm实例只有一个堆空间堆是jvm启动的时候就被创建#xff0c;大小也确定了。大小可以用参数设置。堆是jvm管理的一块最大的内存空间 核心区域#xff0c;是垃圾回收的重点区域堆可以位…4.堆 堆 一个Java程序main方法对应一个jvm实例一个jvm实例只有一个堆空间堆是jvm启动的时候就被创建大小也确定了。大小可以用参数设置。堆是jvm管理的一块最大的内存空间 核心区域是垃圾回收的重点区域堆可以位于物理上不连续的内存空间中但在逻辑上是连续的所有的线程共享堆堆里还有TLAB线程私有的缓冲区 Thread Local Allocation Buffer所有的对象及数组分配在堆里如果对象在方法里面没有逃逸理论上可以栈上分配取决于jvm设计者的选择在方法结束后堆中的对象不会被马上移除垃圾回收时才会移除内存细分现代垃圾收集器大部分都基于分代收集理论设计 新生区新生代年轻代 养老区老年区老年代 永久区永久代Java7及之前堆内存逻辑上分为三部分 新生代 Young/New Generation Space 又被分为 Eden区和 Survivor 0区 Survivor 1区不空的为from区 空的为to区to区是下一次要放的区域老年代 Old/Tenure Generation Space永久代 Permanent Space Java8及之后堆内存逻辑上分为三部分新生代 老年代 元空间Meta Space事实上永久代 / 元空间 具体是方法区实现当面试题问 jdk8内存结构有什么改变要提出 永久代变成元空间 设置堆空间大小 -Xms 用于设置堆空间年轻代老年代不含元空间初始大小等价于 -XX:InitialHeapSize) 例子-Xms10m-Xmx 用于设置堆空间最大大小等价于 -XX:MaxHeapSize例子-Xmx10m一旦堆空间超过 -Xmx 的值就会报OOM通常会设置 -Xms -Xmx为一样的值目的是为了能够在Java垃圾回收完之后不用再重新分隔计算堆区的大小从而提高性能默认情况下初始内存 本机内存 / 64最大内存 本机内存 / 4 查看堆空间大小 java代码中 用Runtime.getRuntime().totalMemory() / 1024 / 1024 可以看到堆空间大小 多少兆 【输出的值和设置的值不一样】因为survivor区只能用其中一个所以所有加起来能用的区域就少一些 或者cmd jps查看当前Java程序的进程id 然后jstat -gc 进程id 代码加个 Thread.sleep() 执行长一些或者在vm参数加 -XX:PrintGCDetails 年轻代和老年代 堆中可以分成两类对象 一种是生命周期较短的对象创建和消亡十分迅速另一种是生命周期比较长的对象有些甚至和jvm生命周期一样 配置年轻代和老年代的比例一般用默认值 默认-XX:NewRatio2表示 年轻代/老年代 1/2年轻代占堆 1/3 配置 Eden区和Survivor区比例一般用默认值 默认-XX:SurvivorRatio8 表示 Eden区:Survivor 0:Survivor 18:1:1 不过直接看不是这个比例因为jvm有自适应的内存分配策略可能可以用 -XX:-UseAdaptiveSizePolicy不太管用可以显式设置 -XX:SurvivorRatio8 配置 Eden区最大大小一般不用【同时设置了比例和这个以这个为准】 -Xmn60m 几乎所有的对象都是从Eden区new出来的很大的除外很大的对象在Eden区YGC之后还放不下就放Old区 对象分配过程 1.new的对象先分配到Eden区2.如果Eden区满了会触发young/minor gc垃圾回收Eden区和Survivor区。Eden区 和 Survivor区中没被回收的对象放到空的Survivor区对象的age1。然后再把新对象放到Eden区3.如果这个对象过大在Eden区YGC之后还放不下就放Old区4.young gc后当对象的age15时就是15次垃圾回收都没有被回收就会放到 Old区 这个次数可以设置。-XX:MaxTenuringThreshould15 5.young gc后当Survivor区满了会把Survivor区的对象放到Old区即使不够15次6.young gc后当Old区满了就会 Full gcSurvivor区满了不会触发GC7.若Old区发生了Full gc 后还是满的就会OOM【s0,s1区复制之后有交换谁空谁是to】【关于垃圾回收频繁Eden区很少Old区几乎不在永久区/元空间】 GC 针对hotspot jvm按回收区域分为两大类型一种的部分收集Partial GC)一种是整堆GCfull gc部分收集在一部分堆空间进行垃圾回收 新生代收集 Minor GC / Young GC只收集Eden区 Survivor区老年代收集Major GC / Old GC只收集 Old区 目前只有CMS GC会有单独收集老年代的行为很多时候Major GC 和 Full GC混用需要具体分辨是老年代回收还是整堆回收【很多帖子混淆】 混合收集Mixed GC收集整个新生代及一部分老年代 目前只有G1 GC有这种行为 整堆收集Full GC收集整个堆和方法区年轻代GCMinor GC触发机制 当Eden区空间不足时触发Survivor区满不触发清理的是Eden区和Survivor区因为Java对象大都是朝生夕灭的所以Minor GC非常频繁速度也比较快Minor GC会引发STW暂停其他用户线程等垃圾回收结束用户线程才恢复执行 老年代GCMajor GC / Full GC 这样说不正确其实触发机制 发生在Old 区出现Major GC 一般伴随着一次Minor GC 但非绝对在Parallel Scavenge收集器的收集策略里就有直接进行Major GC 的策略选择过程 也就是在老年代空间不足时会先尝试触发Minor GC。但之后空间如果还不足则触发Major GC Major GC 的速度比Minor GC慢10倍以上STW的时间更长如果Major GC后内存还不足就OOM了 Full GC触发机制后面细讲 1.调用System.gc()时系统建议使用Full GC但是不必然执行2.老年代空间不足3.方法区空间不足4.通过Minor GC 后进入老年代的平均大小大于老年代的可用内存5.由Eden区Survivor space0From Space区向Survivor space1To Space区进行复制时对象大于To Space可用内存则把对象转存到老年区且老年区的可用内存小于该对象大小Full GC 是开发或调优中要尽量避免的这样暂停时间短一点 为什么要把Java堆分代不分代就不能工作嘛 其实不分代可以分代是为了优化GC性能。不分代的话就要扫描整个堆。扫描范围大比较耗时。而进行分代把新创建的对象放到一个区域因为大部分的对象生命周期很短那么就可以对这个区域进行频繁GC。不用扫描整个堆提高效率、 内存分配策略或晋升Promotion规则 优先分配到Eden区大对象直接分配到老年代 尽量避免程序中出现过多的大对象不仅仅是因为占很多空间容易导致频繁Major GC或Full GC。而且因为这些大对象大部分生命周期也很短往往是Major GC或Full GC之后就被清楚掉不值得放到老年代 长期存活的对象分配到老年代动态对象年龄判断 如果Survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半年龄大于或等于该年龄的对象可以直接进入老年代无需等到MaxTenuringThreshold中要求的年龄 空间分配担保 -XX:HandlePromotionFailure 【Java7及以后相当于默认开启此参数改变设置也不起作用】 TLAB——堆全部都是共享的嘛不是 为什么有TLAB因为堆是线程共享区域而对象实例的创建在jvm中非常频繁因此在并发环境下从对中划分空间是线程不安全的。为了避免多个线程操作同一地址需要加锁的话就会影响分配速度。有了TLAB对象在TLAB里创建就不会有线程安全问题尽管不是所有的对象都能在TLAB内创建但是TLAB确实是jvm内存分配的首选所有OpenJDK衍生出的jvm都有TLAB-XX:UseTLAB 设置是否开启TLAB空间默认开启TLAB很小默认占Eden区 1% -XX:TLABWasteTargetPercent 设置TLAB占Eden百分比大小 一旦对象在TLAB分配失败就会在Eden中分配使用时要加锁 栈上分配—逃逸分析—堆是对象分配的唯一选择嘛是逃逸分析-栈上分配也可以不是取决于jvm设计者要不要在栈上分配 如果一个对象经过逃逸分析发现没有逃逸那么就会在栈上分配不分配到堆上减少GC压力而淘宝的TaoBaoVM其中的GCIHGC invisible heap技术实现off-heap将生命周期较长的Java对象从heap中移至heap外并且GC不能管理GCIH内的Java对象从而降低GC回收频率提升GC回收效率**逃逸分析**如果在方法内使用的对象它会在除本方法外的其他地方用到那就是逃逸 比如作为参数传入通过return返回给对象属性赋值使用对象属性逃逸分析其实并不成熟。根本原因是无法保证做了逃逸分析的性能一定比不做好因为逃逸分析也是一个相对耗时的过程。极端点就是经过逃逸分析发现没有一个对象是逃逸的那么分析的过程就白白浪费了一些性能。虽然不成熟但是也是即时编译器优化技术中一个十分重要的手段。重点【通过逃逸分析jvm会在栈上分配那些不会逃逸的对象这种理论上是可行的但是这取决于jvm设计者的选择。Oracle Hotspot JVM中并没有这样做这一点在逃逸分析相关的文档里已经说明所以可以明确所以的对象实例都是创建在堆上。在实际代码测试中运行速度加快是因为虽然没有在栈上分配但是jvm做了标量替换加快了速度】 参数设置 在Java7及以后Hotspot默认开启逃逸分析如果使用的是较早的版本 -XX:DoEscapeAnalysis 显式开启逃逸分析-XX:PrintEscapeAnalysis 查看逃逸分析的筛选结果 所以能使用局部变量就不要在方法外定义使用逃逸分析jvm能做的优化 1.栈上分配2.同步省略 / 锁消除在动态编译同步块时就是运行时JIT编译器通过逃逸分析判断个对象是否只能从一个线程被访问到。如果是那么JIT编译器在编译这个同步块时会取消对这部分代码的同步。大大提高性能和并发不过字节码文件还是显示有锁的3.分离对象或标量替换【简单的说就是不用对象而是创建几个和对象属性对应的变量】有的对象可能不需要作为一个连续的内存结构存在也可以被访问到那么对象的部分或全部可以不存储在堆而是存储在栈中 标量就是一个无法再分解成更小数据的数据。聚合量就可以再分解。对象就是聚合量JIT阶段如果经过逃逸分析发现对象不会逃逸就会把那个对象分解成若干个标量。这个过程就是标量替换【比如下面两张图】标量替换可以减少对象的创建减少堆内存的分配大大减少堆内存的占用。为栈上分配提供了很好的基础参数-XX:EliminateAllocations 开启了标量替换默认开启允许将对象打散分配在栈上 常用命令 -XX:PrintFlagsInitial:查看所有的参数的默认初始值-XX:PrintFlagsFinal查看所有的参数的最终值可能会存在修改不再是初始值)-Xms:初始堆空间内存默认为物理内存的1/64【常用】-Xmx:最大堆空间内存默认为物理内存的1/4【常用】-Xmn:设置新生代的大小。初始值及最大值-XX:NewRatio:配置新生代与老年代在堆结构的占比-XX:SurvivorRatio:设置新生代中Eden和s0/S1空间的比例-Xx:MaxTenuringThreshold:设置新生代垃圾的最大年龄 【常用】-XX:PrintGCDetails:输出详细的GC处理日志 【常用】打印gc简要信息1.-XX:PrintGC 2.-verbose:go-XX:UseTLAB 设置是否开启TLAB空间默认开启-XX:TLABWasteTargetPercent 设置TLAB占Eden百分比大小-XX:DoEscapeAnalysis 显式开启逃逸分析默认开启-XX:PrintEscapeAnalysis 查看逃逸分析的筛选结果 【常用】-XX:EliminateAllocations 开启了标量替换默认开启允许将对象打散分配在栈上-XX:HandlePromotionFailure:是否设置空间分配担保 【Java7及以后相当于默认开启此参数改变设置也不起作用】 5.方法区 / 元空间 对象类型数据 就是 类的数据 方法区 / 元空间 方法区(Method Area)与Java堆一样是各个线程共享的内存区域。方法区在JVM启动的时候被创建并且它的实际的物理内存空间中和Java堆区一样都可以是不连续的。在Jdk7及以前习惯把方法区称为永久代。Jdk8及以后永久代变成了元空间本质上方法区和永久代不等价。仅是对Hotspot而言是等价的。《Java虚拟机规范》对如何实现方法区不做统一要求。例如BEA 的 JRockit / IBM 的 J9不存在永久代的概念 现在看来当年用永久代不是一个好想法。因为它导致Java程序更容易OOM超过 -XX:MaxPermSize上限 元空间与永久代类似都是对jvm规范中方法区的实现。他们最大的区别在于元空间不是使用Java虚拟机的内存而是使用本地内存 元空间不仅仅是名称变了内部结构也变了 方法区的大小跟堆空间一样可以选择固定大小或者可扩展。 jdk7及以前 -XX:PermSize60m 来设置永久代初始分配空间。默认值是20.75m-XX:MaxPermSize60m 来设置永久代最大可分配空间。32位机器默认64m64位机器默认82m当jvm加载的类超过最大大小会报 java.lang.OutofMemoryError:PermGen space jdk8及以后 元数据区大小可以使用参数-XX:MetaspaceSize100m和-XX:MaxMetaspaceSize指定默认值依赖于平台。window下-XX:MetaspaceSize是21m-XX:MaxMetaspaceSize是-1即没有限制会一直用系统内存 高水位线在jdk8及以后 初始的高水位线 和 -XX:MetaspaceSize的值一样。一旦元空间大小触及到这条线Full GC就会被触发并卸载没用的类即这些类对应的类加载器不再存活然后这个高水位线就会被重置。新的高水位线的值取决于GC后释放了多少元空间。如果释放的空间不足那么在不超过MaxMetaspaceSize时适当提高改值。如果释放的空间过多适当降低该值。如果初始的 高水位线设置过低上述 高水位线调整情况会发生很多次也会频繁Full GC。建议将-XX:MetaspaceSize设置为一个相对较高的值 方法区的大小决定了系统可以保存多少个类如果系统定义了太多的类导致方法区溢出虚拟机同样会抛出内存溢出错误java.lang.OutofMemoryError:PermGen space (java7及之前) 或者 java.lang.OutofMemoryError:Metaspace(java8及以后) 加载大量的第三方的jar包会OOMTomcat部署的工程过多(30-50个) 大量动态的生成反射类 关闭JVM就会释放这个区域的内存。OOM的例子 方法区存的内容 存放已被虚拟机加载的类型信息常量静态变量JIT即时编译器编译后的代码缓存等。随jdk版本不同会有些变化类型信息类接口枚举注解 这个类型的完整有效名称全名包名.类名这个类型直接父类的完整有效名对于接口和Object类都没有父类这个类型的修饰符publicabstractfinal的某个子集这个类型实现的接口的一个有序列表 域(Field)信息就是类的属性信息 jvm必须在方法区中保存类型的所有域的相关信息以及域的声明顺序域的相关信息包括域名称、域类型、域修饰符(public,private,protected,static,final,volatile,transient的某个子集) 方法(Method)信息 jvm必须在方法区中保存所有方法的以下信息以及域的声明顺序方法名称方法的返回类型或 void方法参数的数量和类型按顺序方法的修饰符(public,private,protected,static,final,synchronized,native,abstract的一个子集)方法的字节码bytecodes、操作数栈、局部变量表及大小abstracth和native方法除外异常表abstracth和native方法除外 每个异常处理的开始位置、结束位置、代码处理在程序计数器中的偏移地址、被捕获的异常类的常量池索引 类变量static 没加final的静态变量和类关联在一起随着类的加载而加载它们成为类数据在逻辑上的一部分但是放到堆中加了final的在编译期就确定下来了放到元空间 运行时常量 方法区中的运行时常量池和字节码文件中的常量池的对应起来的 Java中的字节码需要数据支持通常这种数据很大不能直接放到字节码文件中换另一种方式可以存到常量池在动态链接时再引用进来字节码的常量池包括各种字面量和对类型、域、方法的符号引用 jvm为每个已加载的类型类或接口都维护一个常量池通过索引访问运行时常量池 把 字节码文件的常量池中的符号引用 转成了直接引用运行时常量池 相当于Class文件常量池的另一重要特征是具备动态性有些没有的东西会自动加进去运行时常量池类似于传统编程语言中的符号表symbol table但是它所包含的数据却比符号表要更加丰富一些如果创建运行时常量池超过方法区的最大值会OOM 还包含了加载这个字节码文件的 类加载器 方法区的演进细节 jdk1.6及之前有永久代静态变量存放在永久代上 jdk1.7有永久代但已经逐步“去永久代”字符串常量池、静态变量保存到堆中 jdk1.8及以后无永久代类型信息、字段、方法、常量保存在本地内存的元空间。但字符串常量池静态变量仍然在堆中 【要注意如果静态变量是对象的引用。比如public static a new int[10] 无论是哪个jdk数组都是在堆中。因为它是被new 出来的对象。而变量a在不同jdk的位置就不一样】 ![请添加图片描述](https://img-blog.csdnimg.cn/direct/9102dc07d68e44f7be667f656dc955c5.png)为什么元空间要替代永久代 1.为永久代设置大小是很难的。设置小了在某些场景下容易OOM特别是要动态加载很多类的时候。设置大了浪费空间。元空间使用本地内存不用设置仅仅受内存大小的限制2.对永久代进行调优是很困难的。Full GC的时候会对方法区的垃圾回收。判断类型信息是否要清理比较满分。所以Full GC比较麻烦调优也比较困难。用本地内存空间大一些Full GC也会少一些 为什么StringTable要放到堆里 jdk7中将StringTable放入堆中。因为永久代很少进行垃圾回收只有触发Full GC的时候才会进行清理。Full GC只有在老年代空间不足或者永久代空间不足才会触发这就导致StringTable的回收效率不高。在运行过程中大量的字符串常量被创建很多都是不用的放到堆中可以及时清理 方法区的垃圾回收 有的虚拟机支持方法区GC有的没有GC。Java的虚拟机规范对方法区的约束很宽松方法区实不实现垃圾回收都可以。JDK 11的ZGC收集器就不支持类卸载方法区的回收效果比较难以让人满意尤其是类型的卸载条件很苛刻。但是这部分区域的回收有时又确实是必要的。以前Sun公司的Bug列表中曾出现的几个严重的BUG就是因为低版本的hotspot对方法区未完全回收导致内存泄露主要回收两部分内容常量池中废弃的常量 以及 不再使用的类型 常量包括字面量 和 符号引用 符号引用包括类和接口的全限定名字段的名称和描述符方法的名称和描述符 常量只要没有地方使用 就可以回收但是类型是否回收的判断条件很苛刻下面是被回收的前提但是满足了也不一定会回收 1.该类没有实例。也没有任何派送子类的实例2.加载该类的类加载器已经被回收。除非是精心设计的可替换类加载器的场景比如OSGIJSP的重加载等否则很难达成3.该类对应的java.lang.class对象没有被任何地方引用无法在任何地方通过反射访问该类的方法 Java虚拟机被允许对满足上述三个条件的无用类进行回收这里说的仅仅是“被允许”而并不是和对象一样没有引用了就必然会回收。关于是否要对类型进行回收HotSpot虚拟机提供了-Xnoclassgc参数进行控制还可以使用-verbose:class以及-XX:Traceclass-Loading、-XX:TraceClassUnLoading查看类加载和卸载信息 在大量使用反射、动态代理、CGLib等字节码框架动态生成JSP以及OSGi这类频繁自定义类加载器的场景中通常需要Java虚拟机具备类型卸载的能力以保证不会对方法区造成过大的内存压力。
http://www.dnsts.com.cn/news/95926.html

相关文章:

  • 免费看电视的网站有哪些如何用vs2010做网站
  • 快站模板网站推广的渠道
  • 德国 网站建设河南网站建设公
  • 青岛网站推广哪家便宜做企业网站需要准备什么
  • 建设一个个人网站不需要wordpress 显示访客数
  • 备案中又需要建设网站如何做网站推广营销
  • 关键词优化简易长沙自动seo
  • 沈阳网站建设企业六安网站建设推广
  • 男和男人怎么做那个视频网站百度网盘 做网站图床
  • 杭州做肉松饼的网站有多少家济南做网站哪家好怎么选
  • 网站的建设步骤包括什么公司网页设计论文题目大全
  • 北京网站优化实战宁波seo推广优化
  • 上海电子商务网站开发北京 网站建设托管公司
  • 经典重庆论坛畅谈重庆当阳seo外包
  • 网站建设纯免费官网商城网站一般用什么做二次开发
  • 网站营销力吉安律师网站建设
  • 建设银行上虞支行网站wordpress瀑布流展示插件
  • 布吉做网站的公司北京海淀区官网
  • wordpress修改主题文件夹专业网站优化推广
  • 凡科做网站怎么样网站的系统建设方式有哪些方面
  • 马鞍山的网站建设公司海丰网站建设
  • 净化网络环境网站该怎么做关键词全网搜索工具
  • 新农村建设评论网站大型旅游网站
  • 手机软件开发外包昆明搜索引擎的关键词优化
  • 做公司网站客户群体怎么找国际新闻报道
  • 一级域名做网站制作wordpress博客app
  • 网站建设栏目分析服饰网站新闻建设
  • app制作简易网站做游戏模板下载网站有哪些
  • linux 做网站宁波网络公司设计装修
  • 合肥网站制作价格游戏代理加盟