.java的虚拟机分为三大区域: 执行引擎, java运行内存, 类加载器

1.1.Java运行内存分为线程共享区域和线程私有区:

我们大多数初学者用的都是sun公司最早设计的Java HotSpot(TM)虚拟机

(IBMJ9也是java虚拟机, 还有openjdk也是java虚拟机)

  -堆常量池,方法区--都属于线程共享区域,(公有区)

  -本地方法栈,虚拟机栈(我们一般关注的是这个栈),程序计数器--属于线程私有区

具体参考最下边的图

 

 

 

 

1.2.对象的回收: 可达扫描分析, 标记, 回收内存, 整理内存来的内存(小区域的内存不能存储大对象)

可达性分析策略: 分析此对象是否是垃圾(此对象是否被引用)

如何判断对象被回收了?:可以重写对象所属类的finalized方法

 

 

 

 

上图中的c1对象可以当作springscopeSingleton形式的单例对象

提问: springscopeprototype形式时,作用域是不是每次从spring获取都会创建一个新的对象. : 是的()

 

 

 

 

执行System.gc();c1对象没有被销毁,因为map集合(对象池)还引用了这个对象. 只有再次调用beanPool.clear()将对象池清空对象才会被销毁

1.3.启动GC有两种方式:

A.手动启动GC:   将对象的引用置为null, 然后调用System.gc();  就像jdbcclose是在将引用置为null

B.自动启动GC:   内存不够用了会自动启动GC. 例如下边两段代码就是自动启GC

 

 

 

 

如何判定GC运行了?:运行java文件时,点右键然后选run config通过在弹出的窗口中的arguments选项中配置运行时的虚拟机参数-XX:+PrintGCDetails来查看(如图A)

注意: GC垃圾回收器分为小GC和大GC

-年轻代(年轻代分为伊甸园区和幸存区<幸存区又分为:幸存区1和幸存区2>)-GC来负责回收

-老年代-GC来负责回收

-元数区(方法区)

:多次回收没被回收掉就放入老年代

 

 

                                                         A

.java代码的运行简析:

2.1.javac编译器将.java文件编译为.class文件存入硬盘disk

2.2.类加载子系统ClassLoader将字节码夹杂到内存中

2.3.然后将字节码信息分别存入java运行时内存的不同区域(详细解释参考1.1.)

2.4.JVM执行引擎调用引擎内的解释器将java运行时内存中的代码进行翻译(可能将java代码翻译成二进制), JIT负责将已经翻译的内容进行缓存.

2.5.翻译好的内容交给操作系统来执行(windows系统linux系统mac等系统都能执行)

 

 扩展-java类加载机制:

 

 

从上图中我们就更容易理解了,当一个Hello.class这样的文件要被加载时。不考虑我们自定义类加载器,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理会先检查自己是否已经加载过,如果没有再往上。注意这个过程,知道到达Bootstrap classLoader之前,都是没有哪个加载器自己选择加载的。如果父加载器无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException。

 

 

https://blog.csdn.net/shijiujiu33/article/details/104868390

 

https://baijiahao.baidu.com/s?id=1673182721214592210&wfr=spider&for=pc

 

https://blog.csdn.net/weixin_42321815/article/details/89005180

 

早期的智能手机经常发烫并卡死是因为软件中的太多,

 

Java中能用全局变量就别用静态变量引用对象

能用局部变量就别用全局变量引用对象, 因为它们的生命周期长短不同

  

 

.类被读到(加载到)内存中了但没创建对象, 此现象能用代码看到对应过程吗?

对象在构造前肯定得先加载本类

访问静态方法肯定会加载本类, 访问类的属性要看属性的类型和修饰(不一定加载本类)

查看类的加载过程可以在运行代码时配置类加载参数:  -XX:+TraceClassLoading

  

 

 

 

注意: Spring@Lazy是延迟对象的创建,但是它标注的类是需要立即被加载到内存的(但是没立即创建对象)

     如果用@Component注解标注类但没用@Lazy标注的话,类会被立即加载,对象也会立即创建

 

 

扩展名词:

热替换 ---- 用类加载器用新代码直接替换原来代码