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

做的比较好的家具网站首页域名查询万网

做的比较好的家具网站首页,域名查询万网,自己怎么做一个购物平台,wordpress如何应用插件《Java虚拟机规范》里规定除了程序计数器外#xff0c;虚拟机内存的其他几个运行时区域都有发生 OutOfMemoryError 异常的可能#xff0c;我们本文就来演示一下这些错误的使用场景。一. StackOverflowError1.1 写个 bugpublic class StackOverflowErrorDemo {public static v… 《Java虚拟机规范》里规定除了程序计数器外虚拟机内存的其他几个运行时区域都有发生 OutOfMemoryError 异常的可能我们本文就来演示一下这些错误的使用场景。一. StackOverflowError1.1 写个 bugpublic class StackOverflowErrorDemo {public static void main(String[] args) {javaKeeper();}private static void javaKeeper() {javaKeeper();} } JVM 虚拟机栈是有深度的在执行方法的时候会伴随着入栈和出栈上边的方法可以看到main 方法执行后不停的递归迟早把栈撑爆了Exception in thread main java.lang.StackOverflowErrorat oom.StackOverflowErrorDemo.javaKeeper(StackOverflowErrorDemo.java:15) 1.2 原因分析无限递归循环调用最常见原因要时刻注意代码中是否有了循环调用方法而无法退出的情况执行了大量方法导致线程栈空间耗尽方法内声明了海量的局部变量native 代码有栈上分配的逻辑并且要求的内存还不小比如 java.net.SocketInputStream.read0 会在栈上要求分配一个 64KB 的缓存64位 Linux1.3 解决方案修复引发无限递归调用的异常代码 通过程序抛出的异常堆栈找出不断重复的代码行按图索骥修复无限递归 Bug排查是否存在类之间的循环依赖当两个对象相互引用在调用toString方法时也会产生这个异常通过 JVM 启动参数 -Xss 增加线程栈内存空间 某些正常使用场景需要执行大量方法或包含大量局部变量这时可以适当地提高线程栈空间限制二. Java heap spaceJava 堆用于存储对象实例我们只要不断的创建对象并且保证 GC Roots 到对象之间有可达路径来避免 GC 清除这些对象那随着对象数量的增加总容量触及堆的最大容量限制后就会产生内存溢出异常。Java 堆内存的 OOM 异常是实际应用中最常见的内存溢出异常。2.1 写个 bug/*** JVM参数-Xmx12m*/ public class JavaHeapSpaceDemo {static final int SIZE  2 * 1024 * 1024;public static void main(String[] a) {int[] i  new int[SIZE];} } 代码试图分配容量为 2M 的 int 数组如果指定启动参数 -Xmx12m分配内存就不够用就类似于将 XXXL 号的对象往 S 号的 Java heap space 里面塞。Exception in thread main java.lang.OutOfMemoryError: Java heap spaceat oom.JavaHeapSpaceDemo.main(JavaHeapSpaceDemo.java:13) 2.2 原因分析请求创建一个超大对象通常是一个大数组超出预期的访问量/数据量通常是上游系统请求流量飙升常见于各类促销/秒杀活动可以结合业务流量指标排查是否有尖状峰值过度使用终结器Finalizer该对象没有立即被 GC内存泄漏Memory Leak大量对象引用没有释放JVM 无法对其自动回收常见于使用了 File 等资源没有回收2.3 解决方案针对大部分情况通常只需要通过 -Xmx 参数调高 JVM 堆内存空间即可。如果仍然没有解决可以参考以下情况做进一步处理如果是超大对象可以检查其合理性比如是否一次性查询了数据库全部结果而没有做结果数限制如果是业务峰值压力可以考虑添加机器资源或者做限流降级。如果是内存泄漏需要找到持有的对象修改代码设计比如关闭没有释放的连接面试官说说内存泄露和内存溢出加送个知识点三连的终将成为大神~~内存泄露和内存溢出内存溢出(out of memory)是指程序在申请内存时没有足够的内存空间供其使用出现out of memory比如申请了一个 Integer但给它存了 Long 才能存下的数那就是内存溢出。内存泄露( memory leak)是指程序在申请内存后无法释放已申请的内存空间一次内存泄露危害可以忽略但内存泄露堆积后果很严重无论多少内存迟早会被占光。memory leak 最终会导致 out of memory三、GC overhead limit exceededJVM 内置了垃圾回收机制GC所以作为 Javaer 的我们不需要手工编写代码来进行内存分配和释放但是当 Java 进程花费 98% 以上的时间执行 GC但只恢复了不到 2% 的内存且该动作连续重复了 5 次就会抛出 java.lang.OutOfMemoryError:GC overhead limit exceeded 错误俗称垃圾回收上头。简单地说就是应用程序已经基本耗尽了所有可用内存 GC 也无法回收。假如不抛出 GC overhead limit exceeded 错误那 GC 清理的那么一丢丢内存很快就会被再次填满迫使 GC 再次执行这样恶性循环CPU 使用率 100%而 GC 没什么效果。3.1 写个 bug出现这个错误的实例其实我们写个无限循环往 List 或 Map 加数据就会一直 Full GC直到扛不住这里用一个不容易发现的栗子。我们往 map 中添加 1000 个元素。/*** JVM 参数 -Xmx14m -XX:PrintGCDetails*/ public class KeylessEntry {static class Key {Integer id;Key(Integer id) {this.id  id;}Overridepublic int hashCode() {return id.hashCode();}}public static void main(String[] args) {Map m  new HashMap();while (true){for (int i  0; i  1000; i){if (!m.containsKey(new Key(i))){m.put(new Key(i), Number:  i);}}System.out.println(m.size()  m.size());}} } ... m.size()54000 m.size()55000 m.size()56000 Exception in thread main java.lang.OutOfMemoryError: GC overhead limit exceeded 从输出结果可以看到我们的限制 1000 条数据没有起作用map 容量远超过了 1000而且最后也出现了我们想要的错误这是因为类 Key 只重写了 hashCode() 方法却没有重写 equals() 方法我们在使用 containsKey() 方法其实就出现了问题于是就会一直往 HashMap 中添加 Key直至 GC 都清理不掉。????????‍???? 面试官又来了说一下HashMap原理以及为什么需要同时实现equals和hashcode执行这个程序的最终错误和 JVM 配置也会有关系如果设置的堆内存特别小会直接报 Java heap space。算是被这个错误截胡了所以有时在资源受限的情况下无法准确预测程序会死于哪种具体的原因。3.2 解决方案添加 JVM 参数-XX:-UseGCOverheadLimit 不推荐这么干没有真正解决问题只是将异常推迟检查项目中是否有大量的死循环或有使用大内存的代码优化代码dump内存分析检查是否存在内存泄露如果没有加大内存四、Direct buffer memory我们使用 NIO 的时候经常需要使用 ByteBuffer 来读取或写入数据这是一种基于 Channel(通道) 和 Buffer(缓冲区)的 I/O 方式它可以使用 Native 函数库直接分配堆外内存然后通过一个存储在 Java 堆里面的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样在一些场景就避免了 Java 堆和 Native 中来回复制数据所以性能会有所提高。Java 允许应用程序通过 Direct ByteBuffer 直接访问堆外内存许多高性能程序通过 Direct ByteBuffer 结合内存映射文件Memory Mapped File实现高速 IO。4.1 写个 bugByteBuffer.allocate(capability) 是分配 JVM 堆内存属于 GC 管辖范围需要内存拷贝所以速度相对较慢ByteBuffer.allocateDirect(capability) 是分配 OS 本地内存不属于 GC 管辖范围由于不需要内存拷贝所以速度相对较快如果不断分配本地内存堆内存很少使用那么 JVM 就不需要执行 GCDirectByteBuffer 对象就不会被回收这时虽然堆内存充足但本地内存可能已经不够用了就会出现 OOM本地直接内存溢出。/***  VM Options-Xms10m,-Xmx10m,-XX:PrintGCDetails -XX:MaxDirectMemorySize5m*/ public class DirectBufferMemoryDemo {public static void main(String[] args) {System.out.println(maxDirectMemory is:sun.misc.VM.maxDirectMemory() / 1024 / 1024  MB);//ByteBuffer buffer  ByteBuffer.allocate(6*1024*1024);ByteBuffer buffer  ByteBuffer.allocateDirect(6*1024*1024);} } 最大直接内存默认是电脑内存的 1/4所以我们设小点然后使用直接内存超过这个值就会出现 OOM。maxDirectMemory is:5MB Exception in thread main java.lang.OutOfMemoryError: Direct buffer memory 4.2 解决方案Java 只能通过 ByteBuffer.allocateDirect 方法使用 Direct ByteBuffer因此可以通过 Arthas 等在线诊断工具拦截该方法进行排查检查是否直接或间接使用了 NIO如 nettyjetty 等通过启动参数 -XX:MaxDirectMemorySize 调整 Direct ByteBuffer 的上限值检查 JVM 参数是否有 -XX:DisableExplicitGC 选项如果有就去掉因为该参数会使 System.gc() 失效检查堆外内存使用代码确认是否存在内存泄漏或者通过反射调用 sun.misc.Cleaner 的 clean() 方法来主动释放被 Direct ByteBuffer 持有的内存空间内存容量确实不足升级配置五、Unable to create new native thread每个 Java 线程都需要占用一定的内存空间当 JVM 向底层操作系统请求创建一个新的 native 线程时如果没有足够的资源分配就会报此类错误。5.1 写个 bugpublic static void main(String[] args) {while(true){new Thread(() - {try {Thread.sleep(Integer.MAX_VALUE);} catch(InterruptedException e) { }}).start();} } Error occurred during initialization of VM java.lang.OutOfMemoryError: unable to create new native thread 5.2 原因分析JVM 向 OS 请求创建 native 线程失败就会抛出 Unableto createnewnativethread常见的原因包括以下几类线程数超过操作系统最大线程数限制和平台有关线程数超过 kernel.pid_max只能重启native 内存不足该问题发生的常见过程主要包括以下几步JVM 内部的应用程序请求创建一个新的 Java 线程JVM native 方法代理了该次请求并向操作系统请求创建一个 native 线程操作系统尝试创建一个新的 native 线程并为其分配内存如果操作系统的虚拟内存已耗尽或是受到 32 位进程的地址空间限制操作系统就会拒绝本次 native 内存分配JVM 将抛出 java.lang.OutOfMemoryError:Unableto createnewnativethread 错误。5.3 解决方案想办法降低程序中创建线程的数量分析应用是否真的需要创建这么多线程如果确实需要创建很多线程调高 OS 层面的线程最大数执行 ulimia-a 查看最大线程数限制使用 ulimit-u xxx 调整最大线程数限制六、MetaspaceJDK 1.8 之前会出现 Permgen space该错误表示永久代Permanent Generation已用满通常是因为加载的 class 数目太多或体积太大。随着 1.8 中永久代的取消就不会出现这种异常了。Metaspace 是方法区在 HotSpot 中的实现它与永久代最大的区别在于元空间并不在虚拟机内存中而是使用本地内存但是本地内存也有打满的时候所以也会有异常。6.1 写个 bug/*** JVM Options: -XX:MetaspaceSize10m -XX:MaxMetaspaceSize10m*/ public class MetaspaceOOMDemo {public static void main(String[] args) {while (true) {Enhancer enhancer  new Enhancer();enhancer.setSuperclass(MetaspaceOOMDemo.class);enhancer.setUseCache(false);enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) - {//动态代理创建对象return methodProxy.invokeSuper(o, objects);});enhancer.create();}} } 借助 Spring 的 GCLib 实现动态创建对象Exception in thread main org.springframework.cglib.core.CodeGenerationException: java.lang.OutOfMemoryError--Metaspace 6.2 解决方案方法区溢出也是一种常见的内存溢出异常在经常运行时生成大量动态类的应用场景中就应该特别关注这些类的回收情况。这类场景除了上边的 GCLib 字节码增强和动态语言外常见的还有大量 JSP 或动态产生 JSP  文件的应用远古时代的传统软件行业可能会有、基于 OSGi 的应用即使同一个类文件被不同的加载器加载也会视为不同的类等。方法区在 JDK8 中一般不太容易产生HotSpot 提供了一些参数来设置元空间可以起到预防作用-XX:MaxMetaspaceSize 设置元空间最大值默认是 -1表示不限制还是要受本地内存大小限制的-XX:MetaspaceSize 指定元空间的初始空间大小以字节为单位达到该值就会触发 GC 进行类型卸载同时收集器会对该值进行调整-XX:MinMetaspaceFreeRatio 在 GC 之后控制最小的元空间剩余容量的百分比可减少因元空间不足导致的垃圾收集频率类似的还有 MaxMetaspaceFreeRatio七、Requested array size exceeds VM limit7.1 写个 bugpublic static void main(String[] args) {int[] arr  new int[Integer.MAX_VALUE]; } 这个比较简单建个超级大数组就会出现 OOM不多说了Exception in thread main java.lang.OutOfMemoryError: Requested array size exceeds VM limit JVM 限制了数组的最大长度该错误表示程序请求创建的数组超过最大长度限制。JVM 在为数组分配内存前会检查要分配的数据结构在系统中是否可寻址通常为 Integer.MAX_VALUE-2。此类问题比较罕见通常需要检查代码确认业务是否需要创建如此大的数组是否可以拆分为多个块分批执行。八、Out of swap space启动 Java 应用程序会分配有限的内存。此限制是通过-Xmx和其他类似的启动参数指定的。在 JVM 请求的总内存大于可用物理内存的情况下操作系统开始将内容从内存换出到硬盘驱动器。该错误表示所有可用的虚拟内存已被耗尽。虚拟内存Virtual Memory由物理内存Physical Memory和交换空间Swap Space两部分组成。这种错误没见过~~~九、Kill process or sacrifice child操作系统是建立在流程概念之上的。这些进程由几个内核作业负责其中一个名为“ Out of memory Killer”它会在可用内存极低的情况下“杀死”kill某些进程。OOM Killer 会对所有进程进行打分然后将评分较低的进程“杀死”具体的评分规则可以参考 Surviving the Linux OOM Killer。不同于其他的 OOM 错误 Killprocessorsacrifice child 错误不是由 JVM 层面触发的而是由操作系统层面触发的。9.1 原因分析默认情况下Linux 内核允许进程申请的内存总量大于系统可用内存通过这种“错峰复用”的方式可以更有效的利用系统资源。然而这种方式也会无可避免地带来一定的“超卖”风险。例如某些进程持续占用系统内存然后导致其他进程没有可用内存。此时系统将自动激活 OOM Killer寻找评分低的进程并将其“杀死”释放内存资源。9.2 解决方案升级服务器配置/隔离部署避免争用OOM Killer 调优。最后附上一张“涯海”大神的图涯海参考与感谢《深入理解 Java 虚拟机 第 3 版》https://plumbr.io/outofmemoryerrorhttps://yq.aliyun.com/articles/711191https://github.com/StabilityMan/StabilityGuide/blob/master/docs/diagnosis/jvm/exception 往期推荐 这8种常见的SQL错误用法你还在用吗2020-11-27 用好MySQL的21个好习惯2020-11-25 这么简单的三目运算符竟然这么多坑?2020-11-24 关注我每天陪你进步一点点
http://www.pierceye.com/news/125434/

相关文章:

  • 营销型网站试运营调忧仿别人网站
  • 低价网站制作企业云南网站开发公司
  • 成都市建设厅网站查询十九冶成都建设有限公司网站
  • 建电商网站要多少钱建设绿色食品网站
  • 建行个人网上登录入口优化网站结构一般包括
  • 好看的网站页面WordPress知更鸟主题怎样安装
  • 如何查网站是否备案免费建网站代码
  • 曲沃网站开发新注册的公司怎么做网站
  • 企业网站无线端怎么做塑胶科技东莞网站建设
  • 图片发到哪些网站 seo阜沙网站建设
  • 企业开源建站系统大连百度首页优化
  • 通辽做网站有没有智慧软文发稿平台
  • 网站别人做的我自己怎么续费福州网站建站公司
  • 青岛高端网站开发wordpress修改logo地址
  • 做网站实名认证有什么用青岛网站建设运营
  • 大数据分析网站做汽车保养的网站上
  • 网站开发费用一般是多少怎么建设宣传网站
  • 做网站的背景怎么做ps免费模板网站
  • 为什么要建设应急管理网站sketch做网站
  • 做的网站在百度上搜不出来的宁波关键词优化平台
  • 哪里有手机网站建设公司有道网站收录提交入口
  • 赣州网站建设较好的公司贵州网站建设hsyunso
  • 网站建设和管理是教什么科目鹤壁网站建设鹤壁
  • 网站域名和邮箱域名解析国外网站国内做二维码
  • 万万州州微微网站网站建建设设福州建设网站效果图
  • 长安网站建设详细教程鸿科经纬教网店运营推广
  • 微信营销模式有seo短视频网页入口引流推广
  • 做商城网站简单吗长春网站建设服务
  • 工厂弄个网站做外贸如何app开发报价公司
  • 网销网站建设流程如何创建网站挣钱