jvm内存配置参数文件

一、JVM内存模型
根据 JVM 规范,JVM 内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分。

1.虚拟机栈(我们常说的栈、堆和方法区里面的栈stack)
每个线程有一个私有的栈,随着线程的创建而创建。栈里面存着的是一种叫“栈帧”的东西,每个方法会创建一个栈帧,栈帧中存放了局部变量表(基本数据类型和对象引用)、操作数栈、方法出口等信息。栈的大小可以固定也可以动态扩展。当栈调用深度大于JVM所允许的范围,会抛出StackOverflowError的错误,不过这个深度范围不是一个恒定的值。

Java栈也称作虚拟机栈(Java Vitual Machine Stack),也就是我们常常所说的栈。JVM栈是线程私有的,每个线程创建的同时都会创建自己的JVM栈,互不干扰。
Java栈是Java方法执行的内存模型。Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、指向当前方法所属的类的运行时常量池的引用(Reference to runtime constant pool)、方法返回地址(Return Address)和一些额外的附加信息。当线程执行一个方法时,就会随之创建一个对应的栈帧,并将建立的栈帧压栈。当方法执行完毕之后,便会将栈帧出栈。因此可知,线程当前执行的方法所对应的栈帧必定位于Java栈的顶部。
局部变量表:用来存储方法中的局部变量(包括在方法中声明的非静态变量以及函数形参)。对于基本数据类型的变量,则直接存储它的值,对于引用类型的变量,则存的是指向对象的引用。局部变量表的大小在编译期就可以确定其大小了,因此在程序执行期间局部变量表的大小是不会改变的。
操作数栈:栈最典型的一个应用就是用来对表达式求值。在一个线程执行方法的过程中,实际上就是不断执行语句的过程,而归根到底就是进行计算的过程。因此可以这么说,程序中的所有计算过程都是在借助于操作数栈来完成的。指向运行时常量池的引用:因为在方法执行的过程中有可能需要用到类中的常量,所以必须要有一个引用指向运行时常量。
方法返回地址:当一个方法执行完毕之后,要返回之前调用它的地方,因此在栈帧中必须保存一个方法返回地址。
2.堆(heap)
自己画的示意图,不太规范,只能表示大概的意思(我理解的)

Java中的堆是用来存储对象实例以及数组(当然,数组引用是存放在Java栈中的)。堆是被所有线程共享的,因此在其上进行对象内存的分配均需要进行加锁,这也导致了new对象的开销是比较大的。在JVM中只有一个堆。堆是Java垃圾收集器管理的主要区域,Java的垃圾回收机制会自动进行处理。
Sun Hotspot JVM为了提升对象内存分配的效率,对于所创建的线程都会分配一块独立的空间TLAB(Thread Local Allocation Buffer),其大小由JVM根据运行的情况计算而得,在TLAB上分配对象时不需要加锁,因此JVM在给线程的对象分配内存时会尽量的在TLAB上分配,在这种情况下JVM中分配对象内存的性能和C基本是一样高效的,但如果对象过大的话则仍然是直接使用堆空间分配。
堆空间分为老年代和年轻代。刚创建的对象存放在年轻代,而老年代中存放生命周期长久的实例对象。年轻代中又被分为Eden区和两个Survivor区(From Space和To Space)。新的对象分配是首先放在Eden区,Survivor区作为Eden区和Old区的缓冲,在Survivor区的对象经历若干次GC仍然存活的,就会被转移到老年代。 当一个对象大于eden区而小于old区(老年代)的时候会直接扔到old区。 而当对象大于old区时,会直接抛出OutOfMemoryError(OOM)。
3.方法区
在方法区中,存储了每个类的信息(包括类的名称、修饰符、方法信息、字段信息)、类中静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息以及编译器编译后的代码等。程序中通过Class对象的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,同时方法区域也是全局共享的,在一定的条件下它也会被GC,在这里进行的GC主要是方法区里的常量池和类型的卸载。当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。

jdk1.7之前:方法区位于永久代(Permanent Generation),永久代和堆相互隔离,永久代的大小在启动JVM时可以通过-XX:PermSize -XX:MaxPermSize设置初始空间和最大空间;
jdk.7:存储在永久代的部分数据就已经转移到Java Heap或者Native memory。但永久代仍存在于JDK 1.7中,并没有完全移除,譬如符号引用(Symbols)转移到了native memory;字符串常量池(interned strings)转移到了Java heap;类的静态变量(class statics variables )转移到了Java heap;
jdk1.8:仍然保留方法区的概念,只不过实现方式不同。取消永久代,方法存放于元空间(Metaspace),元空间仍然与堆不相连,但与堆共享物理内存,逻辑上可认为在堆中。
移除了永久代(PermGen),替换为元空间(Metaspace);
永久代中的 class metadata 转移到了 native memory(本地内存,而不是虚拟机);
永久代中的 interned Strings 和 class static variables 转移到了 Java heap;
永久代参数 (PermSize MaxPermSize) -> 元空间参数(MetaspaceSize MaxMetaspaceSize)。
注意: Native memory:本地内存,也称为C-Heap,是供JVM自身进程使用的。当Java Heap空间不足时会触发GC,但Native memory空间不够却不会触发GC。)

4.程序计数器(Program Counter Register
程序计数器(Program Counter Register),也有称作为PC寄存器。

由于在JVM中,多线程是通过线程轮流切换来获得CPU执行时间的,因此,在任一具体时刻,一个CPU的内核只会执行一条线程中的指令,因此,为了能够使得每个线程都在线程切换后能够恢复在切换之前的程序执行位置,每个线程都需要有自己独立的程序计数器,并且不能互相被干扰,否则就会影响到程序的正常执行次序。因此,可以这么说,程序计数器是每个线程所私有的。
在JVM规范中规定,如果线程执行的是非native(本地)方法,则程序计数器中保存的是当前需要执行的指令的地址;如果线程执行的是native方法,则程序计数器中的值是undefined。
由于程序计数器中存储的数据所占空间的大小不会随程序的执行而发生改变,因此,对于程序计数器是不会发生内存溢出现象(OutOfMemory)的。
5.本地方法栈
JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。本地方法栈与Java栈的作用和原理非常相似。区别只不过是Java栈是为执行Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的。在JVM规范中,并没有对本地方法栈的具体实现方法以及数据结构作强制规定,虚拟机可以自由实现它。在HotSopt虚拟机中直接就把本地方法栈和Java栈合二为一。

二、JVM常用参数配置
打印GC详细信息-XX:+PrintGCDetails
Heap
PSYoungGen total 37888K, used 26384K [0x00000000d6180000, 0x00000000d8b80000, 0x0000000100000000)
eden space 32768K, 80% used [0x00000000d6180000,0x00000000d7b44178,0x00000000d8180000)
from space 5120K, 0% used [0x00000000d8680000,0x00000000d8680000,0x00000000d8b80000)
to space 5120K, 0% used [0x00000000d8180000,0x00000000d8180000,0x00000000d8680000)
ParOldGen total 86016K, used 0K [0x0000000082400000, 0x0000000087800000, 0x00000000d6180000)
object space 86016K, 0% used [0x0000000082400000,0x0000000082400000,0x0000000087800000)
Metaspace used 8410K, capacity 9382K, committed 9600K, reserved 1056768K
class space used 1104K, capacity 1303K, committed 1408K, reserved 1048576K
PSYoungGen Total = eden + from(to) = 32768 + 5120 = 37888K

[0x00000000d6180000(低边界), 0x00000000d8b80000(当前边界), 0x0000000100000000(最高边界))

(0x0000000100000000-0x00000000d6180000)/1024/1024=670.5M

将gc日志导入到指定的位置-Xloggc:D:/log/gc.log

每次一次GC后,都打印堆信息-XX:+PrintHeapAtGC
Java HotSpot(TM) 64-Bit Server VM (25.131-b11) for windows-amd64 JRE (1.8.0_131-b11), built on Mar 15 2017 01:23:53 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 8240240k(2285968k free), swap 12391624k(1821244k free)
CommandLine flags: -XX:InitialHeapSize=131843840 -XX:MaxHeapSize=2109501440 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
{Heap before GC invocations=1 (full 0):
PSYoungGen total 37888K, used 25063K [0x00000000d6180000, 0x00000000d8b80000, 0x0000000100000000)
eden space 32768K, 76% used [0x00000000d6180000,0x00000000d79f9f30,0x00000000d8180000)
from space 5120K, 0% used [0x00000000d8680000,0x00000000d8680000,0x00000000d8b80000)
to space 5120K, 0% used [0x00000000d8180000,0x00000000d8180000,0x00000000d8680000)
ParOldGen total 86016K, used 0K [0x0000000082400000, 0x0000000087800000, 0x00000000d6180000)
object space 86016K, 0% used [0x0000000082400000,0x0000000082400000,0x0000000087800000)
Metaspace used 8161K, capacity 9052K, committed 9216K, reserved 1056768K
class space used 1073K, capacity 1250K, committed 1280K, reserved 1048576K
0.460: [GC (Allocation Failure) [PSYoungGen: 25063K->3649K(37888K)] 25063K->3665K(123904K), 0.0556133 secs] [Times: user=0.00 sys=0.00, real=0.06 secs]
Heap after GC invocations=1 (full 0):
PSYoungGen total 37888K, used 3649K [0x00000000d6180000, 0x00000000d8b80000, 0x0000000100000000)
eden space 32768K, 0% used [0x00000000d6180000,0x00000000d6180000,0x00000000d8180000)
from space 5120K, 71% used [0x00000000d8180000,0x00000000d85104d0,0x00000000d8680000)
to space 5120K, 0% used [0x00000000d8680000,0x00000000d8680000,0x00000000d8b80000)
ParOldGen total 86016K, used 16K [0x0000000082400000, 0x0000000087800000, 0x00000000d6180000)
object space 86016K, 0% used [0x0000000082400000,0x0000000082404000,0x0000000087800000)
Metaspace used 8161K, capacity 9052K, committed 9216K, reserved 1056768K
class space used 1073K, capacity 1250K, committed 1280K, reserved 1048576K
}
{Heap before GC invocations=2 (full 0):
4.监控类的加载-XX:+TraceClassLoading
[Loaded java.util.concurrent.ConcurrentHashMap$Traverser from D:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.util.concurrent.ConcurrentHashMap$BaseIterator from D:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.util.concurrent.ConcurrentHashMap$ValueIterator from D:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded org.junit.platform.engine.TestExecutionResult from file:/C:/Users/ASUS/.m2/repository/org/junit/platform/junit-platform-engine/1.5.2/junit-platform-engine-1.5.2.jar]
[Loaded org.junit.platform.engine.TestExecutionResult$Status from file:/C:/Users/ASUS/.m2/repository/org/junit/platform/junit-platform-engine/1.5.2/junit-platform-engine-1.5.2.jar]
[Loaded org.junit.jupiter.api.extension.TestWatcher from file:/C:/Users/ASUS/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.5.2/junit-jupiter-api-5.5.2.jar]
[Loaded org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$258/99451533 from org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor]
[Loaded org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$259/84739718 from org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor]
...
打印类的信息-XX:+PrintClassHistogram,需要按下Ctrl+Break后才会打印类的信息,否则不会起作用
num #instances #bytes class name

1: 890617 470266000 [B
2: 890643 21375432 java.util.HashMap$Node
3: 890608 14249728 java.lang.Long
4: 13 8389712 [Ljava.util.HashMap$Node;
5: 2062 371680 [C
6: 463 41904 java.lang.Class
分配堆的大小-Xmx20m -Xms5m,-Xmx为最大堆空间、-Xms为最小堆空间,如果分配的堆太小,然后创建的对象大于堆的最大值,就会出现Exception in thread "main" java.lang.OutOfMemoryError: Java heap space的异常
//可以通过如下方式获取最大、空闲和总共
System.out.print("Xmx=");
System.out.println(Runtime.getRuntime().maxMemory()/1024.0/1024+"M");

System.out.print("free mem=");
System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024+"M");

System.out.print("total mem=");
System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024+"M");

//执行结果打印
Xmx=18.5M
free mem=3.26397705078125M
total mem=18.5M
7.设置新生代的大小-Xmn
//-Xmn2m
PSYoungGen total 1536K, used 1008K [0x00000000ffe00000, 0x0000000100000000, 0x0000000100000000)
eden space 1024K, 98% used [0x00000000ffe00000,0x00000000ffefc158,0x00000000fff00000)
from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
to space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)

PSYoungGen = eden space + from space + to space = 2M
8.设置两个Survivor区和eden的比-XX:SurvivorRatio=2
设置两个Survivor区和eden的比
8表示 两个Survivor :eden=2:8,即一个Survivor占年轻代的1/10
9.设置年轻代和老年代的比值-XX:NewRatio=4
新生代(eden+2*s)和老年代(不包含永久区)的比值
4 表示 新生代:老年代=1:4,即年轻代占堆的1/5
10.OOM时导出堆到文件-XX:+HeapDumpOnOutOfMemoryError和指定OOM导出的地址-XX:HeapDumpPath
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:log/test.dump

执行结果:
java.lang.OutOfMemoryError: Java heap space
Dumping heap to D:log/test.dump ...

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.example.webserver.WebserverApplicationTests.contextLoads(WebserverApplicationTests.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
Heap dump file created [14489693 bytes in 0.074 secs]
11.OOM时指定执行的脚本-XX:OnOutOfMemoryError
在OOM时,执行一个脚本 "-XX:OnOutOfMemoryError=D:/tools/jdk1.7_40/bin/printstack.bat %p“
当程序OOM时,在D:/a.txt中将会生成线程的dump
可以在OOM时,发送邮件,甚至是重启程序
12.设置永久区的初始大小和最大值-XX:PermSize -XX:MaxPermSize(jdk1.8之前的参数);1.8之后使用-XX:MetaspaceSize -XX:MaxMetaspaceSize
示例: -XX:MetaspaceSize=20m -XX:MaxMetaspaceSize=25m

设置永久区(元空间)的初始空间和最大空间
他们表示,一个系统可以容纳多少个类型
超出的最大空间的时候会出现OutOfMemoryError: Metaspace

设置栈的大小-Xss
通常只有几百K
决定了函数调用的深度
每个线程都有独立的栈空间
局部变量、参数 分配在栈上
超出就会报出java.lang.StackOverflowError异常
三、参数使用
通过修改idea(eclipse)启动参数的设置

如果是以jar包启动,只需要将启动参数附加在java -jar *.jar之后

以war包执行(Tomcat为例)
打开catalin.bat或者catalin.sh
增加一行set "JAVA_OPTS=-Xss120k -XX:+PrintGCDetails -XX:+PrintHeapAtGC -Xloggc:D:/log/gc.log",通过JAVA_OPTS设置虚拟机参数
然后启动查看参数的配置效果
四、注意
根据实际事情调整新生代和幸存代的大小
官方推荐新生代占堆的3/8
幸存代占新生代的1/10
在OOM时,记得Dump出堆,确保可以排查现场问题

原文地址:https://www.cnblogs.com/liangh5/p/13878122.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


jinfo 命令可以用来查看 Java 进程运行的 JVM 参数,命令如下:[root@admin ~]# jinfo --helpUsage: jinfo [option] <pid> (to connect to running process) jinfo [option] <executable <core> (to connect to a core file) jinfo [option] [serve
原文链接:https://www.cnblogs.com/niejunlei/p/5987611.htmlJava Virtual Machine Stacks,线程私有,生命周期与线程相同,描述的是Java方法执行的内存模型:每一个方法执行的同时都会创建一个栈帧(Stack Frame),由于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法的执行就对应着栈帧在虚拟机栈中的入栈,出栈...
java 语言, 开发者不能直接控制程序运行内存, 对象的创建都是由类加载器一步步解析, 执行与生成与内存区域中的; 并且jvm有自己的垃圾回收器对内存区域管理, 回收; 但是我们已经可以通过一些工具来在程序运行时查看对应的jvm内存使用情况, 帮助更好的分析与优化我们的代码;jps查看系统中有哪些java进程jps 命令类似与 linux 的 ps 命令,但是它只列出系统中所有的 Java 应用程序。 通过 jps 命令可以方便地查看 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息
1.jvm的简单抽象模型:  2.类加载机制     双亲委派模型是为了防止jdk核心类库被篡改,如果需要打破可以重写Classloader.loadClass方法。r 双亲委派模型:一个类加载器收到一个类的加载请求,他会先判断自身是否已存在该类,如果不存在上抛给上一级类加载器ClassLoad
堆外内存JVM启动时分配的内存,称为堆内存,与之相对的,在代码中还可以使用堆外内存,比如Netty,广泛使用了堆外内存,但是这部分的内存并不归JVM管理,GC算法并不会对它们进行回收,所以在使用堆外内存时,要格外小心,防止内存一直得不到释放,造成线上故障。堆外内存的申请和释放JDK的ByteBuffe
1.springboot和tomcat2.springcloud的请求如何通过网关鉴权?3.springmvc启动时组件的加载顺序?4.mybatis如何同时更新三条记录5.hibernate实现级联更新6.一个web程序应用程序启动时的加载流程7.如何向www.baidu.com地址发出请求时,并获取相应?8.???9.谈谈你对tcp/iptelnetudp协
堆设置-Xms256M:初始堆大小256M,默认为物理内存的1/64-Xmx1024M:最大堆大小1024M,默认为物理内存的1/4,等于与-XX:MaxHeapSize=64M-Xmn64M:年轻代大小为64M(JDK1.4后支持),相当于同时设置NewSize和MaxNewSize为64M-XX:NewSize=64M:初始年轻代大小-XX:MaxNewSize=256M:最大年轻代大小(默认
一.概述收集算法(JVM之垃圾回收-垃圾收集算法)是内存回收的抽象策略,垃圾收集器就是内存回收的具体实现。JVM规范对于垃圾收集器的应该如何实现没有任何规定,因此不同的厂商、不同版本的虚拟机所提供的垃圾收集器差别较大,这里只看HotSpot虚拟机。就像没有最好的算法一样,垃圾收集器
Java中的堆是JVM所管理的最大的一块内存空间,主要用于存放各种类的实例对象,如下图所示: 在Java中,堆被划分成两个不同的区域:新生代(Young)、老年代(Old)。新生代(Young)又被划分为三个区域:Eden、S0、S1。 这样划分的目的是为了使JVM能够更好的管理堆内存中的对象,包
JVM深入理解JVM(4)——如何优化JavaGC「译」 PostedbyCrowonAugust21,2017本文翻译自SangminLee发表在Cubrid上的”BecomeaJavaGCExpert”系列文章的第三篇《HowtoTuneJavaGarbageCollection》,本文的作者是韩国人,写在JDK1.8发布之前,虽然有些地
 JVM深入理解JVM(2)——GC算法与内存分配策略 PostedbyCrowonAugust10,2017说起垃圾收集(GarbageCollection,GC),想必大家都不陌生,它是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如Scala等)程序员在提升开
运行时数据区  线程独有本地方法栈、虚拟机栈、程序计数器这些与线程对应的数据区会随着线程开始和结束创建和销毁  整体公有元数据区(又称方法区)、堆区会随着虚拟机启动而创建,随着虚拟机退出而销毁 
java整个堆大小设置:Xmx和Xms设置为老年代存活对象的3-4倍,即FullGC之后的老年代内存占用的3-4倍。永久代PermSize和MaxPermSize设置为老年代存活对象的1.2-1.5倍年轻代Xmx的设置为老年代存活对象的1-1.5倍老年代的内存大小设置为老年代存活对象的2-3倍BTW: Sun官方建议年轻代
栈顶缓存(Top-of-StackCashing)技术基于栈式架构得虚拟机所使用的零地址指令更加紧凑,但完成一项操作的时候必然使用更多的入栈和出栈指令,这同时也就意味着将需要更多的指令分派次数和内存读写次数 由于操作数是存储在内存重的,因此频繁地执行内存读/写操作必然影响速度。 综上
自用。同样的代码在不同的平台生成的机器码是不一样的,为什么java代码生成的字节码文件,能在不同的平台运行?因为不同版本的jdk里面的虚拟机会屏蔽不同操作系统在底层硬件与指令上的区别。栈:线程栈,局部变量存放栈内存区域。线程(分配一个栈)运行分配栈将局部变量放入内存。怎么放:栈
jconsole监控:1.java启动命令加上参数java-Djava.rmi.server.hostname=172.16.17.247-Dcom.sun.management.jmxremote-Dcom.sun.management.jmxremote.port=2099-Dcom.sun.management.jmxremote.authenticate=false-Dcom.sun.management.jmxremote.ssl=false -XX:+Unlock
类加载器分类publicclassStackStruTest{publicstaticvoidmain(String[]args){//对用户自定义个类来说:默认使用系统类加载器进行加载-----AppClassLoaderClassLoaderclassLoader=StackStruTest.class.getClassLoader();System.out.p
堆体系结构一个JVM实例只存在一个堆内存,堆内存的大小是可调节的。类加载器读取类文件后,需要把类、方法、常量、变量放在堆内存中,保存所有引用类型的真实信息,以方便执行器指向,堆内存分为三个部分:年轻代、老年代、永久代。Java7之前,堆内存在逻辑上分为:年轻代、老年代、永久代。物
JVM深入理解JVM(5)——虚拟机类加载机制 PostedbyCrowonAugust21,2017在Class文件中描述的各种信息,最终都需要加载到虚拟机中之后才能运行和使用。而虚拟机中,而虚拟机如何加载这些Class文件?Class文件中的信息进入到虚拟机中会发生什么变化?本文将逐步解答这
保存(持久化)对象及其状态到内存或者磁盘Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在