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

做网站做的好的公司免费域名注册教程

做网站做的好的公司,免费域名注册教程,浅谈京东企业的电子商务网站建设,珠海企业建站模板一 对象内存分配 1.1 运行时数据区域 1.2 常见java应用启动JVM参数#xff1a; -Xss#xff1a;每个线程的栈大小(单位kb)-Xms#xff1a;堆的初始大小#xff0c;默认物理内存的1/64,示例#xff1a;-Xms:4g -Xms:10m-Xmx#xff1a;堆的最大可用大小#xff0c;默认物…一 对象内存分配 1.1 运行时数据区域  1.2 常见java应用启动JVM参数 -Xss每个线程的栈大小(单位kb)-Xms堆的初始大小默认物理内存的1/64,示例-Xms:4g -Xms:10m-Xmx堆的最大可用大小默认物理内存的1/4-Xmn新生代大小-XX:NewRatio默认2表示新生代占老年代的1/2占整个堆内存的1/3-XX:SurvivorRatio默认8表示一个survivor区占用1/8的Eden内存即1/10的新生代内存 1.3 关于元空间的JVM参数 -XX:MaxMetaspaceSize元空间最大大小默认-1即不限制即受限于本地内存大小-XX:MetaspaceSize元空间触发FullGC的初始阈值(元空间无固定初始大小)单位字节默认是21M左右元空间使用大小达到该值会触发FullGC进行类型卸载同时jvm收集器会对该值进行调整 如果如果释放了大量空间适当降低该值如果释放了很少的空间且元空间大小未超过-XX:MaxMetaspaceSize适当提高-XX:MetaspaceSize值 由于调整元空间大小需要FullGC这是非常昂贵的操作如果应用在启动的时候发生大量的FullGC通常是由于元空间发生了大小调整基于这种情况一般建议在JVM参数中将-XX:MetaspaceSize -XX:MaxMetaspaceSize设置成一样大小并且初始值比默认值要大比如对于8G物理内存的机器可以将元空间大小设置为256M、512M 1.4 StackOverflowError问题 源码 public class StackOverflowHelper {static int count;static void doBusiness(){count;doBusiness();}/*** 启动jvm参数 -Xms256m -Xmx256m -Xss128k默认1M* param args*/public static void main(String[] args) {try{doBusiness();}catch (Exception e){System.out.println(e);}} } 运行结果 java -Xms256m -Xmx256m -Xss128k com.ddu.jvm.StackOverflowHelper Exception in thread main java.lang.StackOverflowErrorat com.ddu.jvm.StackOverflowHelper.doBusiness(StackOverflowHelper.java:6)at com.ddu.jvm.StackOverflowHelper.doBusiness(StackOverflowHelper.java:7)at com.ddu.jvm.StackOverflowHelper.doBusiness(StackOverflowHelper.java:7)at com.ddu.jvm.StackOverflowHelper.doBusiness(StackOverflowHelper.java:7)at com.ddu.jvm.StackOverflowHelper.doBusiness(StackOverflowHelper.java:7)at com.ddu.jvm.StackOverflowHelper.doBusiness(StackOverflowHelper.java:7)at com.ddu.jvm.StackOverflowHelper.doBusiness(StackOverflowHelper.java:7)at com.ddu.jvm.StackOverflowHelper.doBusiness(StackOverflowHelper.java:7)总结-Xss设置越小说明一个线程栈里能分配的栈帧数量就越少但是对于JVM整体来说可以开启的线程数就会更多  二 内存分配场景 2.1 对象在Eden区分配 一般情况下新对象会在新生代的eden区分配内存空间但Eden区没有足够的空间进行分配时虚拟机会发起一次MinorGC MinorGC/YoungGC指发生在新生代的垃圾收集动作MinorGC非常频繁回收速度一般比较快MajorGC/FullGC一般回收老年代、年轻代、方法区的垃圾MajorGC的速度一般会比MinorGC慢10倍以上 示例1 package com.ddu.jvm;public class GcHelper {public static void main(String[] args) {byte[] data1, data2, data3, data4, data5, data6;data1 new byte[1024 * 1000 * 10 * 6];} } java -Xms256M -Xmx256M -XX:PrintGCDetails com.ddu.jvm.GcHelper HeapPSYoungGen total 76288K, used 63932K [0x00000000fab00000, 0x0000000100000000, 0x0000000100000000)eden space 65536K, 97% used [0x00000000fab00000,0x00000000fe96f250,0x00000000feb00000)from space 10752K, 0% used [0x00000000ff580000,0x00000000ff580000,0x0000000100000000)to space 10752K, 0% used [0x00000000feb00000,0x00000000feb00000,0x00000000ff580000)ParOldGen total 175104K, used 0K [0x00000000f0000000, 0x00000000fab00000, 0x00000000fab00000)object space 175104K, 0% used [0x00000000f0000000,0x00000000f0000000,0x00000000fab00000)Metaspace used 2605K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 284K, capacity 386K, committed 512K, reserved 1048576K总结当前示例中Eden区占用比例达到97%基本已经被占满 示例2 在【实例1】的基础上继续分配内存 package com.ddu.jvm;public class GcHelper {public static void main(String[] args) {byte[] data1, data2, data3, data4, data5, data6;data1 new byte[1024 * 1000 * 10 * 6];data2 new byte[1024 * 1000 * 8];} } java -Xms256M -Xmx256M -XX:PrintGCDetails com.ddu.jvm.GcHelper [GC (Allocation Failure) [PSYoungGen: 62621K-784K(76288K)] 62621K-60792K(251392K), 0.0305527 secs] [Times: user0.00 sys0.02, real0.03 secs] HeapPSYoungGen total 76288K, used 10723K [0x00000000fab00000, 0x0000000100000000, 0x0000000100000000)eden space 65536K, 15% used [0x00000000fab00000,0x00000000fb4b4c80,0x00000000feb00000)from space 10752K, 7% used [0x00000000feb00000,0x00000000febc4020,0x00000000ff580000)to space 10752K, 0% used [0x00000000ff580000,0x00000000ff580000,0x0000000100000000)ParOldGen total 175104K, used 60008K [0x00000000f0000000, 0x00000000fab00000, 0x00000000fab00000)object space 175104K, 34% used [0x00000000f0000000,0x00000000f3a9a010,0x00000000fab00000)Metaspace used 2605K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 284K, capacity 386K, committed 512K, reserved 1048576K现象 发生了MinorGCfrom区被占用了部分空间有对象转移至老年代 ParOldGen used 60008K说明data1被转移至老年代 总结 由【示例1】可知data1分配完内存之后Eden区已经占用达97%继续在Eden区尝试分配data2因为Eden剩余空间无法放下data2因此触发MinorGCMinorGC期间JVM发现Survivor区无法分配存储data1因此只好把新生代的对象data1提前转移到老年代中去老年代上的空间足够存放data1,所以不会触发FullGC执行完MinorGC之后后面分配的对象如果能够全部放在Eden区的话还是会在Eden区分配 示例3 package com.ddu.jvm;public class GcHelper {public static void main(String[] args) {byte[] data1, data2, data3, data4, data5, data6;data1 new byte[1024 * 1000 * 10 * 6];data2 new byte[1024 * 1000 * 8];data4 new byte[1024 * 1000];data5 new byte[1024 * 1000];data6 new byte[1024 * 1000];} } 运行结果 java -Xms256M -Xmx256M -XX:PrintGCDetails com.ddu.jvm.GcHelper [GC (Allocation Failure) [PSYoungGen: 62621K-800K(76288K)] 62621K-60808K(251392K), 0.0286915 secs] [Times: user0.02 sys0.02, real0.03 secs] HeapPSYoungGen total 76288K, used 12739K [0x00000000fab00000, 0x0000000100000000, 0x0000000100000000)eden space 65536K, 18% used [0x00000000fab00000,0x00000000fb6a8c38,0x00000000feb00000)from space 10752K, 7% used [0x00000000feb00000,0x00000000febc8030,0x00000000ff580000)to space 10752K, 0% used [0x00000000ff580000,0x00000000ff580000,0x0000000100000000)ParOldGen total 175104K, used 60008K [0x00000000f0000000, 0x00000000fab00000, 0x00000000fab00000)object space 175104K, 34% used [0x00000000f0000000,0x00000000f3a9a010,0x00000000fab00000)Metaspace used 2605K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 284K, capacity 386K, committed 512K, reserved 1048576K现象 老年代已占用空间未发生变化 总结 当前示例充分证明了【示例2的总结3】执行完MinorGC之后后面分配的对象如果能够全部放在Eden区的话还是会在Eden区分配 2.2 Eden:Survivor0:Survivor1 大量对象分配在Eden区Eden区慢了后会触发MinorGC可能99%以上的对象会变成垃圾而被回收掉而剩余存活的对象会被挪到空的Survivor0区下次Eden区满后会触发MinorGC把Eden区Survivor0区中存活的对象复制到Survivor区并Eden区和Survivor区垃圾回收因此新生代的对象大部分是朝生夕死存活时间比较多所以JVM默认的8:1:1比例很合适原则让Eden区尽量大Survivor区足够用就可以 其中Eden:Survivor0:Survivor的比例会根据UseAdpativeSizePolicy参数决定是否自动调整 -XX:UseAdpativeSizePolicy动态自动调整Eden:Survivor的比例默认开启 2.3 大对象直接进入老年代 大对象是需要大量连续内存空间的对象(比如数组、字符串)JVM参数 -XX:PretenureSizeThreshold可以设置判断大对象的大小阈值当新对象大小超过设置阈值会跳过新生代分配直接在老年代内存进行分配但是当前参数只有在Serial和ParNew两类收集器下才能生效例如 -XX:PretenureSizeThreshold1000000 -XX:UseSerialGC 为什么需要设置大对象呢 为了避免为大对象分配内存时复制操作降低了垃圾回收效率  2.4 长期存活的对象进行老年代 虚拟机采用了分代收集的思想来管理内存那么内存收回时就必须呀能识别那些对象应该分配在新生代哪些对象应该分配在老年代为什么实现这个功能虚拟机给每个对象设置了一个对象年龄(age)计数器。 如果对象在Eden区分配之后经过一次MindorGC后仍然存活下来了并且可以被Survivor存储则将当前对象的对象年龄1,当对象的年龄增加到一定程度(默认15CMS收集器默认6不同的垃圾收集器略微不同)当前对象就会晋升至老年代中其中可以通过 -XX:MaxTenuringThreshold参数来设置 2.5 对象动态年龄判断 当前存放对象的Survivor(两个Survivor区域同一时刻只有一个Survivor区域存储对象)区域其中一批对象的总大小大于Survivor区域内存大小的50%(-XX:TargetSurvivorRatio可以指定)那么此时大于等于这批对象里面对象年龄最多的所有对象在MinorGC阶段直接被转移至老年代中 例如年龄1年龄2年龄n的多个对象占用内存综合超过Survivor区域的50%此时就会把年龄n(包含n)以上的对象全部转移至老年代 目的让可能长期存货的对象尽早进入老年代 2.6 老年代空间分配担保机制 年轻代进行MinorGC前JVM会计算老年代剩余可用空间LOC 如果LOC小于年轻代里现有的所有对象大小之和(包括垃圾对象),进入步骤2如果配置了-XX:HandlePromotionFailurejdk8默认配置,进入步骤3否则进入步骤4判断老年代的剩余可用大小是否大于之前每一次MinorGC后进入老年代对象的平均大小是则进入步骤4否则进入步骤5触发FullGC针对老年代和新生代一起进行一次垃圾回收如果回收完之后没有足够的空间存储新对象此时就会发生OOM触发MinorGC,GC之后剩余存活需要移动至老年代的对象大小还是大于老年代剩余可用大小触发FullGC如果FullGC后还是没有空间存放新进入的存活对象此时就会发生OOM; 三 对象栈上分配 一般情况下Java中的对象大部分是在堆上进行分配的当对象没有被引用时需要依赖GC进行垃圾回收释放内存如果对象数量比较多会给GC带来较大的压力STW时间较长进而影响系统的整体性能在某些特殊情况下经过逃逸分析后发现一个对象没有逃逸出方法的话可能当前对象会被优化成栈上分配也就不需要在堆上分配内存了 背景 在java的编译提醒中一个java源码文件变成计算机可执行的机器指令的过程中需要进过两阶段编译 第一阶段把java文件转成class文件第二阶段把class文件转成机器指令 其中在第二编译阶段JVM通过解释字节码将其翻译成对应的机器指令逐条读入逐条解析翻译经过解释执行其执行速度会比可执行的二进制字节码程序慢一些这就是传统的JVM解释器的功能为了提高整个过程的效率引入了JIT(即时编译)技术 标量与聚合量 标量指一个无法可被继续分解的对象java中的基本数据类型就是标量。聚合量与标量对立的对象就是聚合量聚合量就是可以被进一步分解的对象 逃逸基本原理和逃逸状态 分析对象动态作用域当一个对象在方法内被定义后它可能会被外部方法引用例如 对象作为当前方法的返回值被外部调用方法使用或者对象作为参数传递给其他方法使用这种称之为方法逃逸可能被外部线程访问到比如赋值给可以在其他线程中访问的实例变量这种称之为线程逃逸 从不逃逸方法逃逸线程逃逸称为对象由低到高的不同逃逸程度逃逸大概分类如下 全局逃逸对象逃逸出当前方法和线程。例如存储在静态变量中的对象、存储在转义对象的变量中、作为当前方法的结果返回的对象参数逃逸对象做为参数传递或由参数引用在调用期间不会全局逃逸这个状态是通过分析被调用方法的字节码来确定的没有逃逸对象只在方法内部使用没有发生逃逸该对象是一个标量可替换对象这意味着当前变量可以进行栈上分配 逃逸分析 代码 public class UserEscapeAnalysisHelper {public static void main(String[] args) throws InterruptedException {long start System.currentTimeMillis();for (int i 0; i 100000000; i) {alloc();}System.out.println(System.currentTimeMillis()-start);Thread.sleep(1000 * 100000);}private static void alloc(){User user new User();}static class User{} } 上述代码使用for循环在代码中创建1亿User对象。其中alloc()方法中定义了User对象但是没有在方法外部引用它也就是说这个对象并不会逃逸到alloc方法外部开启逃逸分析情况下经过JIT的逃逸分析可以对内存分配进行优化 逃逸分析和标量替换必要同时开启JVM才能进行内存分配的优化自JDK8开始默认开启逃逸分析和标量替换 具体演示过程如下 涉及到的命令如下 命令        说明-XX:DoEscapeAnalysis开启逃逸分析(JDK8起默认开启)-XX:-DoEscapeAnalysis关闭逃逸分析-XX:PrintEscapeAnalysis打印逃逸分析明细-XX:EliminateAllocations开启标量替换-XX:-EliminateAllocations关闭标量替换-XX:PrintEliminateAllocations打印标量替换明细-XX:PrintGC打印gc过程 关闭逃逸分析和标量替换 java -Xmx4g -Xms4g -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:PrintGC com.ddu.jvm.UserEscapeAnalysisHelper 在关闭逃逸分析的情况下堆中总共创建了340w个实例虽然alloc方法中创建的User对象没有逃逸到方法外部但是还是会被分配到堆内存中也就是说如果没有JIT编译器优化没有逃逸分析技术正常情况下就应该是分配到堆内存中  开启逃逸分析和标量替换 java -Xmx4g -Xms4g -XX:DoEscapeAnalysis -XX:EliminateAllocations -XX:PrintGC com.ddu.jvm.UserEscapeAnalysisHelper 开启了逃逸分析在jmap打印内存情况下看在堆中只有11w个User对象也就是说经过JIT优化之后堆内存中分配的对象数量从340w降到了11w。 总结栈上分配依赖于逃逸分析和标量替换 四 垃圾对象判定算法 4.1 引用计数法 4.2 可达性分析算法 五 常见的引用类型 java的引用类型一般分四种强引用、软引用、弱引用、虚引用 5.1 强引用 5.2 软引用 5.3 弱引用 5.4 虚引用 5.5 finalize()方法最终判定对象是否存活 5.6 如何判定一个类是无用的类
http://www.zqtcl.cn/news/155123/

相关文章:

  • 为什么访问外国网站速度慢沈阳网站公司排名
  • 网站建设+泰安网站项目建设策划方案
  • 微信人生里面微网站怎么做wordpress 第三方登录 代码
  • 做商城网站哪里高端大气网站案例
  • 网站做项目网站设计公司深
  • 学校做网站及费用建设网站有何要求
  • 河北邢台移动网站建设宁波网站开发公司电话
  • 免费建立个人网站申请seo搜索引擎优化推广
  • 如何拷贝服务器里面网站做备份金融网站怎么做的
  • 什么网站做的比较好网上投资网站建设
  • 公司网站运营方案策划办网站怎么赚钱
  • 贾汪区建设局网站设计接单兼职网站
  • 东莞商城网站建设哪家便宜wordpress 插件路径
  • 网站服务器 安全快递系统专注快递企业网站开发
  • 旅游网站平台建设的方案深圳移动官网网站建设
  • 如何建设企业人力资源网站网站建设和网络优化的区别
  • 辽宁网站设计影响网站用户体验
  • cms网站如何修改黄山建设网站
  • 宾爵手表官方网站小熊源码网
  • 荥阳网站建设网站建设取得了
  • 江苏省住房和城乡建设厅 官方网站wordpress点击下载
  • 找家里做的工作上哪个网站公司取名三个字推荐
  • 购物网站建设源码wordpress 多多进宝
  • 重庆定制网站建设地址晋安福州网站建设
  • 360建网站了解深圳网站页面设计
  • 哪些网站首页做的好蛋糕网站内容规划
  • 富阳市网站息壤服务器网站打不开
  • 中文建站模板客户做网站嫌贵了
  • 做网站用jquery做网站都有哪些费用
  • 网站知识安卓studio制作一个简单app