今天工作中遇到一个用于缓存数据到内存的静态变量Stringbuffer;当缓存数据大小达到5M的时候就把该缓存数据写到S3上;然后清空该缓存buffer;看了这段代码我觉得是不是有点问题;先贴大概的代码
package com.sanpang.demo;
public class StaticVariableDemo {
//定义一个缓存buffer;存放数据到内存;数据达到5M的时候就写到S3上面;
public static StringBuffer cachebuffer = new StringBuffer();
public static void main(String[] args) {
cachebuffer.append("存的数据 达到5M");
//将数据存到S3 ;然后清空buffer
cachebuffer = new StringBuffer();
}
}
看了以上代码;我担心一个问题是这里通过new 个新对象来起到清空buffer的作用:
cachebuffer = new StringBuffer();
这样的写法会不会导致这个静态变量cachebuffer 之前引用的实例还存在不;有没有被GC回收;如果没有会不会出现OOM的问题?
带着这个疑惑问了很多技术小伙伴得到的回复都没有解决我疑惑的问题;于是自己分析了一下;自己主要疑惑的一个是这个静态变量在JVM 中的内存存储;还有一个疑惑就是这个静态对象之前引用的地址所指向的实例会不会被GC立即回收;
带着问题看了些关于JVM GC 的文章;下面写下我看了这些文章的自己的理解;不对的地方希望可以指出;
首先是JVM内存结构
根据《java虚拟机规范》规定,JVM的基本结构一般如下图所示
Paste_Image.png
从左图可知,JVM主要包括四个部分:
1.类加载器(ClassLoader):在JVM启动时或者在类运行时将需要的class加载到JVM中。(右图表示了从java源文件到JVM的整个过程,可配合理解。 关于类的加载机制,可以参考http://blog.csdn.net/tonytfjing/article/details/47212291)
2.执行引擎:负责执行class文件中包含的字节码指令(执行引擎的工作机制,这里也不细说了,这里主要介绍JVM结构);