- 浏览: 307761 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (165)
- hadoop (47)
- linux (11)
- nutch (7)
- hbase (7)
- solr (4)
- zookeeper (4)
- J2EE (1)
- jquery (3)
- java (17)
- mysql (14)
- perl (2)
- compass (4)
- suse (2)
- memcache (1)
- as (1)
- roller (1)
- web (7)
- MongoDB (8)
- struts2 (3)
- lucene (2)
- 算法 (4)
- 中文分词 (3)
- hive (17)
- noIT (1)
- 中间件 (2)
- maven (2)
- sd (0)
- php (2)
- asdf (0)
- kerberos 安装 (1)
- git (1)
- osgi (1)
- impala (1)
- book (1)
- python 安装 科学计算包 (1)
最新评论
-
dandongsoft:
你写的不好用啊
solr 同义词搜索 -
黎明lm:
meifangzi 写道楼主真厉害 都分析源码了 用了很久. ...
hadoop 源码分析(二) jobClient 通过RPC 代理提交作业到JobTracker -
meifangzi:
楼主真厉害 都分析源码了
hadoop 源码分析(二) jobClient 通过RPC 代理提交作业到JobTracker -
zhdkn:
顶一个,最近也在学习设计模式,发现一个问题,如果老是看别人的博 ...
Java观察者模式(Observer)详解及应用 -
lvwenwen:
木南飘香 写道
高并发网站的架构
JVM学习笔记-方法区示例与常量池解析(Method Area Use And Constant Pool Resolution)
博客分类: jvmjava方法区
As an example of how the Java Virtual Machine uses the information it stores in the method area, consider these classes:
为了展示虚拟机如何使用方法区中的信息,我们举个例子,看下面这个类:
begin
// On CD-ROM in file jvm/ex2/Lava.java
class Lava {
private int speed = 5; // 5 kilometers per hour
void flow() {
}
}
// On CD-ROM in file jvm/ex2/Volcano.java
class Volcano {
public static void main(String[] args) {
Lava lava = new Lava();
lava.flow();
}
}
end
The following paragraphs describe how an implementation might execute the first instruction in the bytecodes for the main() method of the Volcano application. Different implementations of the Java Virtual Machine can operate in very different ways. The following description illustrates one way--but not the only way--a Java Virtual Machine could execute the first instruction of Volcanoís main() method.
下面的段落描述了某个实现是如何执行Volcano程序中main()方法的字节码中第一条指令的。不同的虚拟机实现可能会用完全不同的方法来操作,下 面描述的只是其中一种可能,但是并不是仅有的一种,下面看一下Java虚拟机是如何执行Volcano程序中main()方法的第一条指令的。
To run the Volcano application, you give the name "Volcano" to a Java Virtual Machine in an implementation-dependent manner. Given the name Volcano, the virtual machine finds and reads in file Volcano.class. It extracts the definition of class Volcano from the binary data in the imported class file and places the information into the method area. The virtual machine then invokes the main() method, by interpreting the bytecodes stored in the method area. As the virtual machine executes main(), it maintains a pointer to the constant pool (a data structure in the method area) for the current class (class Volcano).
要运行Volcano程序,首先得以某种“依赖于实现的”方式告诉虚拟机“Volcano”这个名字。之后虚拟机将找到并读入相应的class文件 “Volcano.class”,然后他会从导入的class文件里的二进制数据中提取类型信息并放到方法区中。通过执行保存在方法区中的字节码,虚拟机开始执行main()方法,在执行时,他会一直持有指向当前类(Volcano类)的常量池(方法区中的一个数据结构)的指针。
Note that this Java Virtual Machine has already begun to execute the bytecodes for main() in class Volcano even though it hasnít yet loaded class Lava. Like many (probably most) implementations of the Java Virtual Machine, this implementation doesnít wait until all classes used by the application are loaded before it begins executing main(). It loads classes only as it needs them.
注意,虚拟机开始执行Volcano类中main()方法的字节码的时候,尽管Lava类还没被装载,但是和大多数(也许是所有)虚拟机实现一样,他不会等到把程序中用到的所有类都装载后才开始运行程序。恰好相反,他只需在需要时才装载相应的类 。
main()'s first instruction tells the Java Virtual Machine to allocate enough memory for the class listed in constant pool entry one. The virtual machine uses its pointer into Volcanoís constant pool to look up entry one and finds a symbolic reference to class Lava. It checks the method area to see if Lava has already been loaded.
main()的第一条指令告知虚拟机为列在常量池第一项的类分配足够的内存。所以虚拟机使用指向Volcano常量池的指针找到第一项,发现他是一个对Lava类的符号引用,然后他就检查方法区,看Lava类是否已经被装载了。
The symbolic reference is just a string giving the classís fully qualified name: "Lava". Here you can see that the method area must be organized so a class can be located--as quickly as possible--given only the classís fully qualified name. Implementation designers can choose whatever algorithm and data structures best fit their needs--a hash table, a search tree, anything. This same mechanism can be used by the static forName() method of class Class, which returns a Class reference given a fully qualified name.
这个符号引用仅仅是一个给出了类Lava的全限定名“Lava”的字符串。为了能让虚拟机尽可能快地从一个名称找到类,设计者应当选择最佳的数据结构和算法。这里可以采用各种方法,如散列表、搜索树等等。同样的算法也可以用于实现Class类的forName()方法,这个方法根据给定的全限定名返回 Class引用。
When the virtual machine discovers that it hasnít yet loaded a class named "Lava," it proceeds to find and read in file Lava.class. It extracts the definition of class Lava from the imported binary data and places the information into the method area.
当虚拟机发现还没有装载过名为“Lava”的类时,他就开始查找并装载文件“Lava.class”,并把从读入的二进制数据中提取的类型信息放在方法区中。
The Java Virtual Machine then replaces the symbolic reference in Volcanoís constant pool entry one, which is just the string "Lava", with a pointer to the class data for Lava. If the virtual machine ever has to use Volcanoís constant pool entry one again, it wonít have to go through the relatively slow process of searching through the method area for class Lava given only a symbolic reference, the string "Lava". It can just use the pointer to more quickly access the class data for Lava. This process of replacing symbolic references with direct references (in this case, a native pointer) is called constant pool resolution. The symbolic reference is resolved into a direct reference by searching through the method area until the referenced entity is found, loading new classes if necessary.
紧接着,虚拟机以一个直接指向方法区Lava类数据的指针类替换常量池第一项(就是那个字符串“Lava”)----以后就可以用这个指针来快速访问Lava类了。这个替换过程称为常量池解析 ,即把常量池中的符号引用替换为直接引用。这是通过在方法区中搜索被引用的元素实现的,在这期间可能又需要装载其他类。在这里,我们替换掉符号引用的“直接引用”是一个本地指针。
Finally, the virtual machine is ready to actually allocate memory for a new Lava object. Once again, the virtual machine consults the information stored in the method area. It uses the pointer (which was just put into Volcanoís constant pool entry one) to the Lava data (which was just imported into the method area) to find out how much heap space is required by a Lava object.
终于,虚拟机转变为一个新的Lava对象分配内存。此时,它又需要方法区中的信息。还记得刚刚放到Volcano类常量池第一项的指针吗?现在虚拟机用它 来访问Lava类型信息(此前刚放到方法区中的),找到其中记录的这样一个信息:一个Lava对象需要分配多少堆空间。
A Java Virtual Machine can always determine the amount of memory required to represent an object by looking into the class data stored in the method area. The actual amount of heap space required by a particular object, however, is implementation-dependent. The internal representation of objects inside a Java Virtual Machine is another decision of implementation designers. Object representation is discussed in more detail later in this chapter.
Java虚拟机总能够通过存储于方法区的类型信息来实现一个对象需要的内存,但是,某一个特定对象事实上需要多少内存,是跟特定实现相关的。对象在虚拟机内部的表示由实现的设计者来决定的。
Once the Java Virtual Machine has determined the amount of heap space required by a Lava object, it allocates that space on the heap and initializes the instance variable speed to zero, its default initial value. If class Lavaís superclass, Object, has any instance variables, those are also initialized to default initial values. (The details of initialization of both classes and objects are given in Chapter 7, "The Lifetime of a Class.")
当java虚拟机确定了一个Lava对象的大小后,它就在堆上分配这么大的空间,并把这个对象实例的变量speed初始化为默认初始值0.假如Lava类的超类Object也有实例变量,这也会在此时被初始化为相应的默认值。
The first instruction of main() completes by pushing a reference to the new Lava object onto the stack. A later instruction will use the reference to invoke Java code that initializes the speed variable to its proper initial value, five. Another instruction will use the reference to invoke the flow() method on the referenced Lava object.
当把新生成的Lava对象的引用压到栈中,main()方法的第一条指令也完成了。接下来的指令通过这个引用调用Java代码(该代码把speed变量初始化为正确初始值5)。另外一条指令将用这个引用调用Lava对 象引用的flow()方法。
博客分类: jvmjava方法区
As an example of how the Java Virtual Machine uses the information it stores in the method area, consider these classes:
为了展示虚拟机如何使用方法区中的信息,我们举个例子,看下面这个类:
begin
// On CD-ROM in file jvm/ex2/Lava.java
class Lava {
private int speed = 5; // 5 kilometers per hour
void flow() {
}
}
// On CD-ROM in file jvm/ex2/Volcano.java
class Volcano {
public static void main(String[] args) {
Lava lava = new Lava();
lava.flow();
}
}
end
The following paragraphs describe how an implementation might execute the first instruction in the bytecodes for the main() method of the Volcano application. Different implementations of the Java Virtual Machine can operate in very different ways. The following description illustrates one way--but not the only way--a Java Virtual Machine could execute the first instruction of Volcanoís main() method.
下面的段落描述了某个实现是如何执行Volcano程序中main()方法的字节码中第一条指令的。不同的虚拟机实现可能会用完全不同的方法来操作,下 面描述的只是其中一种可能,但是并不是仅有的一种,下面看一下Java虚拟机是如何执行Volcano程序中main()方法的第一条指令的。
To run the Volcano application, you give the name "Volcano" to a Java Virtual Machine in an implementation-dependent manner. Given the name Volcano, the virtual machine finds and reads in file Volcano.class. It extracts the definition of class Volcano from the binary data in the imported class file and places the information into the method area. The virtual machine then invokes the main() method, by interpreting the bytecodes stored in the method area. As the virtual machine executes main(), it maintains a pointer to the constant pool (a data structure in the method area) for the current class (class Volcano).
要运行Volcano程序,首先得以某种“依赖于实现的”方式告诉虚拟机“Volcano”这个名字。之后虚拟机将找到并读入相应的class文件 “Volcano.class”,然后他会从导入的class文件里的二进制数据中提取类型信息并放到方法区中。通过执行保存在方法区中的字节码,虚拟机开始执行main()方法,在执行时,他会一直持有指向当前类(Volcano类)的常量池(方法区中的一个数据结构)的指针。
Note that this Java Virtual Machine has already begun to execute the bytecodes for main() in class Volcano even though it hasnít yet loaded class Lava. Like many (probably most) implementations of the Java Virtual Machine, this implementation doesnít wait until all classes used by the application are loaded before it begins executing main(). It loads classes only as it needs them.
注意,虚拟机开始执行Volcano类中main()方法的字节码的时候,尽管Lava类还没被装载,但是和大多数(也许是所有)虚拟机实现一样,他不会等到把程序中用到的所有类都装载后才开始运行程序。恰好相反,他只需在需要时才装载相应的类 。
main()'s first instruction tells the Java Virtual Machine to allocate enough memory for the class listed in constant pool entry one. The virtual machine uses its pointer into Volcanoís constant pool to look up entry one and finds a symbolic reference to class Lava. It checks the method area to see if Lava has already been loaded.
main()的第一条指令告知虚拟机为列在常量池第一项的类分配足够的内存。所以虚拟机使用指向Volcano常量池的指针找到第一项,发现他是一个对Lava类的符号引用,然后他就检查方法区,看Lava类是否已经被装载了。
The symbolic reference is just a string giving the classís fully qualified name: "Lava". Here you can see that the method area must be organized so a class can be located--as quickly as possible--given only the classís fully qualified name. Implementation designers can choose whatever algorithm and data structures best fit their needs--a hash table, a search tree, anything. This same mechanism can be used by the static forName() method of class Class, which returns a Class reference given a fully qualified name.
这个符号引用仅仅是一个给出了类Lava的全限定名“Lava”的字符串。为了能让虚拟机尽可能快地从一个名称找到类,设计者应当选择最佳的数据结构和算法。这里可以采用各种方法,如散列表、搜索树等等。同样的算法也可以用于实现Class类的forName()方法,这个方法根据给定的全限定名返回 Class引用。
When the virtual machine discovers that it hasnít yet loaded a class named "Lava," it proceeds to find and read in file Lava.class. It extracts the definition of class Lava from the imported binary data and places the information into the method area.
当虚拟机发现还没有装载过名为“Lava”的类时,他就开始查找并装载文件“Lava.class”,并把从读入的二进制数据中提取的类型信息放在方法区中。
The Java Virtual Machine then replaces the symbolic reference in Volcanoís constant pool entry one, which is just the string "Lava", with a pointer to the class data for Lava. If the virtual machine ever has to use Volcanoís constant pool entry one again, it wonít have to go through the relatively slow process of searching through the method area for class Lava given only a symbolic reference, the string "Lava". It can just use the pointer to more quickly access the class data for Lava. This process of replacing symbolic references with direct references (in this case, a native pointer) is called constant pool resolution. The symbolic reference is resolved into a direct reference by searching through the method area until the referenced entity is found, loading new classes if necessary.
紧接着,虚拟机以一个直接指向方法区Lava类数据的指针类替换常量池第一项(就是那个字符串“Lava”)----以后就可以用这个指针来快速访问Lava类了。这个替换过程称为常量池解析 ,即把常量池中的符号引用替换为直接引用。这是通过在方法区中搜索被引用的元素实现的,在这期间可能又需要装载其他类。在这里,我们替换掉符号引用的“直接引用”是一个本地指针。
Finally, the virtual machine is ready to actually allocate memory for a new Lava object. Once again, the virtual machine consults the information stored in the method area. It uses the pointer (which was just put into Volcanoís constant pool entry one) to the Lava data (which was just imported into the method area) to find out how much heap space is required by a Lava object.
终于,虚拟机转变为一个新的Lava对象分配内存。此时,它又需要方法区中的信息。还记得刚刚放到Volcano类常量池第一项的指针吗?现在虚拟机用它 来访问Lava类型信息(此前刚放到方法区中的),找到其中记录的这样一个信息:一个Lava对象需要分配多少堆空间。
A Java Virtual Machine can always determine the amount of memory required to represent an object by looking into the class data stored in the method area. The actual amount of heap space required by a particular object, however, is implementation-dependent. The internal representation of objects inside a Java Virtual Machine is another decision of implementation designers. Object representation is discussed in more detail later in this chapter.
Java虚拟机总能够通过存储于方法区的类型信息来实现一个对象需要的内存,但是,某一个特定对象事实上需要多少内存,是跟特定实现相关的。对象在虚拟机内部的表示由实现的设计者来决定的。
Once the Java Virtual Machine has determined the amount of heap space required by a Lava object, it allocates that space on the heap and initializes the instance variable speed to zero, its default initial value. If class Lavaís superclass, Object, has any instance variables, those are also initialized to default initial values. (The details of initialization of both classes and objects are given in Chapter 7, "The Lifetime of a Class.")
当java虚拟机确定了一个Lava对象的大小后,它就在堆上分配这么大的空间,并把这个对象实例的变量speed初始化为默认初始值0.假如Lava类的超类Object也有实例变量,这也会在此时被初始化为相应的默认值。
The first instruction of main() completes by pushing a reference to the new Lava object onto the stack. A later instruction will use the reference to invoke Java code that initializes the speed variable to its proper initial value, five. Another instruction will use the reference to invoke the flow() method on the referenced Lava object.
当把新生成的Lava对象的引用压到栈中,main()方法的第一条指令也完成了。接下来的指令通过这个引用调用Java代码(该代码把speed变量初始化为正确初始值5)。另外一条指令将用这个引用调用Lava对 象引用的flow()方法。
发表评论
-
博客地址变更
2013-08-16 10:29 1247all the guys of visiting the bl ... -
java 中object 方法
2012-11-02 07:39 1594Java中Object的方法 构造方法摘要 Object() ... -
java 容易引起内存泄漏的几大原因
2012-02-14 16:01 1779容易引起内存泄漏的几 ... -
jvm 调优2
2012-02-09 17:37 55B-树 是一种多路搜索树(并不是二叉的): 1 ... -
java 反射机制
2012-02-09 11:24 1092JAVA反射机制的学习 JAVA语言中的反射机制: ... -
java nio 编程
2012-02-06 14:13 1102转自:http://yangguangfu.iteye.com ... -
JVM调优 (2)
2012-01-13 14:00 874JVM调优 1. Heap设定与垃圾回收 J ... -
jvm 启动参数
2012-01-13 13:58 980转载自:http://www.blogjava ... -
Java虚拟机(JVM)参数简介
2012-01-13 13:14 1296Java虚拟机(JVM)参数简介 在Java、J2EE大型 ... -
Java 哈夫曼编码反编码的实现
2011-12-23 09:52 1333Java 哈夫曼编码反编码 ... -
离线并发与锁机制
2011-12-15 15:47 925离线并发与锁机制 离线并发的来源 在W ... -
Java观察者模式(Observer)详解及应用
2011-12-14 11:19 4846Java观察者模式(Observer)详解及应用 由于网站 ... -
解决zookeeper linux下无法启动的问题
2011-12-05 14:20 4774在linux下安装zookeeper时,出现了如下的错误: ... -
使用Java NIO编写高性能的服务器
2011-12-04 17:28 1139使用Java NIO编写高性能的服务器 从JDK 1.5开 ... -
jvm 参数设置
2011-10-18 16:01 1144jvm 参数设置 /usr/local/jdk/bin/ja ... -
eclipse 成功发布工程 但访问不到项目
2011-09-29 17:48 1392前提: 将其他的 工程 copy 一份修改了名字 在eclip ... -
java 生成 静态html
2011-09-15 15:43 1596java 生成html 网上的大部分资料都是 用 ##tit ...
相关推荐
【标题】"nginx-upstream-jvm-route-1.15" 涉及的核心知识点是Nginx的upstream模块与JVM路由的整合,特别针对Nginx 1.15版本。这个项目旨在解决在配置Nginx时遇到的特定错误提示“nginx: [emerg] invalid parameter ...
在JDK 1.6及以前,字符串常量池位于方法区(也称为永久代),而在JDK 1.7中,随着永久代逐渐被移除,字符串常量池被移到堆中。到了JDK 1.8及以后,永久代完全消失,元空间取代了它的位置,但字符串常量池仍然存在于...
《JVM调优实战与常量池详解》 在Java开发中,JVM(Java虚拟机)的性能优化是一项至关重要的任务。通过对JVM进行调优,我们可以显著提升应用程序的运行效率,减少内存消耗,避免不必要的垃圾回收(GC)带来的性能...
在JDK8中,JVM内存结构发生了显著变化,尤其是元空间(MetaSpace)替代了永久代(Permanent Generation)作为方法区的一部分。这种方法区的调整是由于永久代存在的一些问题,比如大小设定困难,容易引发溢出,以及给...
赠送jar包:metrics-jvm-3.1.5.jar; 赠送原API文档:metrics-jvm-3.1.5-javadoc.jar; 赠送源代码:metrics-jvm-3.1.5-sources.jar; 赠送Maven依赖信息文件:metrics-jvm-3.1.5.pom; 包含翻译后的API文档:...
- **方法区**:存储已加载的类信息、常量、静态变量等,JDK8后改为元空间,使用本地内存,可以调整`-XX:MetaspaceSize`和`-XX:MaxMetaspaceSize`来控制大小。 7. **编译优化(JIT编译器)** - **热点代码识别**:...
代码如下:failed to create jvm error code -4 这一般应是内存不够用所致,解决方法参考如下。 打开 Android Studio 安装目录下的bin目录,查找并打开文件 studio.exe.vmoptions,修改代码: 代码如下:-Xmx512m 为...
赠送jar包:metrics-jvm-3.1.5.jar; 赠送原API文档:metrics-jvm-3.1.5-javadoc.jar; 赠送源代码:metrics-jvm-3.1.5-sources.jar; 赠送Maven依赖信息文件:metrics-jvm-3.1.5.pom; 包含翻译后的API文档:...
JVM性学习笔记-基本原理,内存模型,JVM参数设置,类加载器原理,JDK自带工具
本篇学习笔记主要介绍如何利用一系列工具来查看和监控JVM的各种运行时信息,包括但不限于JVM进程与参数查看、垃圾收集信息、JVM锁信息等内容。 #### 二、查看JVM进程及参数 ##### 1. JPS - **用途**:列出主机上...
《深入JVM---JVM命令---invokespecial》 在Java虚拟机(JVM)的世界里,`invokespecial`指令扮演着至关重要的角色。它主要用于执行对象的构造方法(即`<init>`方法),以及调用私有方法和父类非静态方法。本文将...
第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: ...
本篇JVM学习笔记主要关注对象声明、相关内存分配方法以及虚拟内存的物理和虚拟寻址概念。 首先,我们来看对象声明。在Java中,对象是在堆上创建的。例如,`CHeapObj` 类展示了如何在C++中模拟Java对象在堆上的分配...
"nginx-upstream-jvm-route-0.1.tar.gz"正是为了解决这个问题而设计的一个解决方案。 首先,让我们了解一下Nginx的Upstream模块。Upstream模块允许Nginx将接收到的请求转发到一组后端服务器,可以根据配置的策略...
项目名为"jvm-rs-main",通过这个项目,我们可以深入学习Rust语言与JVM的交互,以及如何构建一个简化版的JVM。 一、Rust语言的魅力 Rust是一种系统级编程语言,它强调安全、并发和速度。它的内存管理模型避免了空...
在Java内存管理中,堆(Heap)、栈(Stack)、常量池(Constant Pool)和方法区(Method Area)是四个核心概念,它们在Java程序运行时扮演着不同的角色。 首先,方法区是用来存放类的信息、常量、静态变量等数据的...
- **示例**:`-XX:SurvivorRatio=4` 表示Eden区与单个Survivor区的比例为4:1。 #### 7. -XX:MaxPermSize - **定义**:设置永久代(PermGen space)的最大大小。 - **示例**:`-XX:MaxPermSize=16m` 设置永久代最大...
本篇JVM学习笔记主要涵盖了以下几个核心知识点: 1. **运行时数据区**: - **程序计数器**:记录当前线程执行的字节码的行号,用于线程恢复执行时跳转到正确位置。 - **Java虚拟机栈**:每个方法执行时创建的栈帧...
### JVM学习笔记 #### JVM内存模型 (JMM) JVM内存模型主要分为以下几个部分: - **Java堆**:这是所有线程共享的一块区域,在虚拟机启动时创建。主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 - *...
1. **理解内存区域与内存区域异常**:学习JVM的内存结构,包括程序计数器、Java堆、虚拟机栈、本地方法栈、方法区和运行时常量池等,并了解它们发生异常的原因。 2. **掌握Java堆内存溢出异常的测试**:通过编写...