浅谈假造机内存区
副问题[/!--empirenews.page--]
1. Java 假造机内存区概述 我们在编写措施时,常常会碰着OOM(out of Memory)以及内存走漏等题目。为了停止呈现这些题目,我们起首必需对JVM的内存分别有个详细的熟悉。JVM将内存首要分别为:要领区、假造机栈、当处所法栈、堆、措施计数器。 2. Java 假造机运行时数据区 2.1. 运行时数据区分别 2.1.1 运行时数据区图 2.1.2 运行时数据区包罗
2.2. 要领区(Method Area) 2.2.1 要领区的观念 要领区又叫静态区,存放的是已加载的类的根基信息、常量、静态变量等。它是各个线程共享地区。 例如说我们在写Java代码时,每个线水平可以会见统一个类的静态变量工具。因为行使反射机制的缘故起因,假造机很难展望哪谁人类信息不再行使,因此这块地区的接纳很难。 2.2.1.1 静态块和非静态块有什么区别?
2.2.2 要领区的特点 线程间共享地区 2.2.3 要领区的非常 对这块地区首要是针对常量池接纳,值得留意的是JDK1.7已经把常量池转移到堆内里了。同样,当要领区无法满意内存分派需求时,会抛出OutOfMemoryError。制造要领区内存溢出,留意,必需在JDK1.6及之前版本才会导致要领区溢出,缘故起因后头表明,执行之前,可以把假造机的参数-XXpermSize和-XX:MaxPermSize限定要领区巨细。 代码清单如下:
输出非常功效:
备注:网上的例子运行后会抛出java.lang.OutOfMemoryError:PermGen space非常。 2.2.3.1 关于String的intern()函数 intern()的浸染: 假如当前的字符串在常量池中不存在,则放入到常量池中。 上面的代码不绝将字符串添加到常量池,最终必定会导致内存不敷,抛出要领区的OOM。表明一下,为什么必需将上面的代码在JDK1.6之前运行。我们前面提到JDK1.7后,把常量池放入到堆空间中,这导致intern()函数的成果差异,代码清单如下:
在场景jdk6,输出功效:
在场景jdk7,输出功效:
为什么了? 缘故起因是在JDK1.6中,intern()要了解把初次碰着的字符串实例复制到常量池中,返回的也是常量池中的字符串的引用,而StringBuilder建设的字符串实例是在堆上面,以是肯定不是统一个引用,返回false。在JDK1.7中,intern要领不再复制实例,常量池中只生涯初次呈现的实例的引用,因此intern()返回的引用和由StringBuilder建设的字符串实例是统一个。为什么对str2较量返回的是false呢?这是由于,JVM中内部在加载类的时辰,就已经有”java”这个字符串,不切合“初次呈现”的原则,因此返回false。 2.2.4 要领区的浸染 要领区存放的是类信息、常量、静态变量等,是各个线程共享地区 2.2.5 要领区的运用 通过过配置假造机的参数 -XXpermSize 以及 -XX:MaxPermSize 限定要领区巨细 2.2.6 要领区的行使场景 2.3. 假造机栈(VM Stack) 2.3.1 假造机栈的观念 假造机栈描写的是Java要领执行的内存模子: 每个要领被执行的时辰城市同时建设一个栈帧 (StackFrame)用于存储局部变量表、操纵栈、动态链接、要领出口等信息。每一个要领被挪用直至执行完成的进程,就对应着一个栈帧在假造机栈中从入栈到出栈的进程 2.3.1.1 局部变量表 局部变量表存放了编译器禁止的各类根基数据范例(boolean、byte、char、short、int、float、long、double)、工具引用(Object reference)和字节码指令地点(returnAddress范例)。 2.3.1.1 操纵栈 (编辑:河北网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |