网站首页 > 技术文章 正文
Java中的数据类型
分为两大类:基本数据类型和引用数据类型
基本变量类型:在方法中定义的非全局的基本数据类型变量,具体内容是存储在栈中,参考:基本数据类型。
引用变量类型:引用数据类型的变量,其具体内容是存放在堆中,而栈中存放的是其具体内容是所在内存的地址,通过变量地址可以找到变量的具体内容。
Java引用类型:
操作内存元素的方法,在C和C++是通过指针完成的,而Java中则是通过“引用”来完成的。Java中一切都被视为对象,操作的标识符实际是对象的一个引用(reference),通过“引用”标识符指向某个对象,就可以通过这个引用来实现操作对象了。
内存模型图:
对应的代码:
package com.what21.demo;
class Memory {
private Integer id;
private String name;
private String desc;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
public class Demo {
public static void main(String[] args) {
// memory引用
Memory memory = new Memory();
method1();
method2();
}
public static void method1() {
}
public static void method2() {
}
}
Java中四种引用类型
JDK.1.2之后,Java对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这4种引用的强度依次减弱。
1、强引用
Java中默认声明的就是强引用,如:
Object object = new Object();
2、软引用
软引用是用来描述一些非必需但仍有用的对象,在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。这种特性常常被用来实现缓存技术,比如:网页缓存,图片缓存等。
JDK1.2之后,用java.lang.ref.SoftReference类来表示软引用。
package com.what21.demo;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
public class SoftReferenceDemo {
static List<SoftReference> list = new ArrayList<>();
private static void testSoftReference() {
byte[] buff = null;
for (int i = 0; i < 10; i++) {
buff = new byte[1024 * 1024];
SoftReference<byte[]> sr = new SoftReference<>(buff);
list.add(sr);
}
//主动通知垃圾回收
System.gc();
// GC够用<==>打印
for (int i = 0; i < list.size(); i++) {
Object obj = ((SoftReference) list.get(i)).get();
System.out.println(obj);
}
System.out.println("buff: " + buff.toString());
}
public static void main(String[] args) {
testSoftReference();
}
}
3、弱引用
弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要JVM开始进行垃圾回收,那些被弱引用关联的对象都会被回收。
JDK1.2之后,用java.lang.ref.WeakReference来表示弱引用。
package com.what21.demo;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
public class WeakReferenceDemo {
static List<WeakReference> list = new ArrayList<>();
private static void testWeakReference() {
for (int i = 0; i < 10; i++) {
byte[] buff = new byte[1024 * 1024];
WeakReference<byte[]> sr = new WeakReference<>(buff);
list.add(sr);
}
// 主动通知垃圾回收
System.gc();
// 打印全是空
for (int i = 0; i < list.size(); i++) {
Object obj = ((WeakReference) list.get(i)).get();
System.out.println(obj);
}
}
public static void main(String[] args) {
testWeakReference();
}
}
4、虚引用
虚引用是最弱的一种引用关系,一个对象仅持有虚引用,和没有任何引用一样,它随时可能会被回收。
JDK1.2之后,用PhantomReference类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个get()方法,而且它的get()方法仅仅是返回一个null,无法通过虚引用来获取对象。
设计目标:为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
虚引用必须要和ReferenceQueue引用队列一起使用。
5、引用队列
引用队列可以与软引用、弱引用以及虚引用一起配合使用,当垃圾回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去。程序可以通过判断引用队列中是否已经加入了引用,来判断被引用的对象是否将要被垃圾回收,这样就可以在对象被回收之前采取一些必要的措施。
与软引用、弱引用不同,虚引用必须和引用队列一起使用。
package com.what21.demo;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.Field;
public class PhantomReferenceDemo {
public static boolean isRun = true;
@SuppressWarnings("static-access")
public static void main(String[] args) throws Exception {
String test = new String("test");
System.out.println(test.getClass() + "@" + test.hashCode());
final ReferenceQueue<String> referenceQueue = new ReferenceQueue<String>();
new Thread() {
public void run() {
while (isRun) {
Object obj = referenceQueue.poll();
if (obj != null) {
try {
Field rereferent = Reference.class.getDeclaredField("referent");
rereferent.setAccessible(true);
Object result = rereferent.get(obj);
System.out.println("gc will collect:"
+ result.getClass() + "@"
+ result.hashCode() + "\t"
+ (String) result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}.start();
PhantomReference<String> abcWeakRef = new PhantomReference<String>(test, referenceQueue);
test = null;
Thread.currentThread().sleep(3000);
System.gc();
Thread.currentThread().sleep(3000);
isRun = false;
}
}
猜你喜欢
- 2024-10-27 从bitmap到布隆过滤器,再到高并发缓存设计策略
- 2024-10-27 强大 WebView2 + 不用写 JavaScript 的 htmx.js 「小轻快」开发桌面程序
- 2024-10-27 《JSP》第13节:JSP中的四大作用域介绍
- 2024-10-27 Java,FreeMarker,模板引擎,通过案例代码,学懂模板引擎
- 2024-10-27 面向对象的三大特性(c++面向对象的三大特性)
- 2024-10-27 教你分析9种 OOM 常见原因及解决方案
- 2024-10-27 可动态调节参数的线程池实现(动态调试工具有哪些)
- 2024-10-27 深入理解Java:类加载机制及反射(java常见类加载器)
- 2024-10-27 JVM系列-6.javap指令介绍(jvm调优)
- 2024-10-27 Java 泛型使用(类、方法、接口协议、类型通配符、通配符上下限)
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)