- 浏览: 209680 次
- 性别:
- 来自: 哈尔滨
文章分类
- 全部博客 (267)
- java.lang (8)
- 问题汇总 (21)
- 异常记录 (20)
- 功能实现 (19)
- 面试总结 (25)
- 技巧总结 (8)
- 常用代码 (4)
- 编程习惯 (3)
- 编码规则 (3)
- java.util (10)
- java.io (1)
- JavaWeb (9)
- MySQL (16)
- SVN (3)
- MyBatis (11)
- Velocity (7)
- 其他知识 (10)
- 人生哲理 (1)
- 人生故事 (1)
- 自我感悟 (1)
- shiro (3)
- 基础知识 (0)
- 问题总结 (1)
- Spring 标签 (1)
- Spring (3)
- 点滴生活 (1)
- DOS (1)
- CAS (4)
- Linux (9)
- Storm (6)
- Shell (1)
- regex (1)
- Collection (4)
- poi (1)
- 经典语句 (1)
- NIO (5)
- concurrent (14)
- RPC (1)
- zookeeper (3)
- 待整理 (2)
- Hadoop (9)
- RabbitMq (2)
- flume (1)
- hive (7)
- hbase (4)
- kafka (1)
- scala (1)
- GC (0)
- java.util.concurrent.atomic (1)
- java.lang.ref (6)
- JVM (2)
- algorithm (1)
- conception (1)
- java key word (1)
- sun.misc (1)
最新评论
使用软引用构建敏感数据的缓存
一、实现原理
1.应用场景
查询频率较高的数据;每次查询均需要通过接口与数据库交互,构建对象仍需要占用一部分内存;即便上次查询的结果仍在内存中还未被GC回收但仍需要再次进行相同的查询操作;
将查询结果放入内存--大量占用内存空间,增加发生内存溢出的可能;
每次都重新查询--当前的查询结果使用完毕后,实现的缺陷在于即使垃圾收集线程还没有进行垃圾收集,包含雇员档案信息的对象仍然完好地保存在内存中,应用程序也要重新构建一个对象
折中的方法,能重新获取那些尚未被回收的Java对象的引用,必将减少不必要的访问,大大提高程序的运行速度
2.软引用的特点
对于软引用关联着的对象,如果内存充足,则垃圾回收器不会回收该对象,如果内存不够了,就会回收这些对象的内存
3.软引用配合引用队列
软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
二、代码实现
实现思想
- 工具类使用懒汉模式的单例实现,避免多线程调用时出现问题,对外接口使用synchronized 关键字修饰
- 构建缓存,使用Hashtable,key:存储内容的唯一标识,value:存储对象的软引用实现;取元素时,若此缓存中存在,则说明此时对象未被回收、或已被回收,但软引用在引用队列中未被清除;若无,说明存储的对象已被GC;
- 构建软引用队列,泛型 T 为要存储的对象,当软引用所依赖的对象被GC回收后,JVM将此软引用加入到与之关联的引用队列中。即,此时在等待GC到达 out of memory 前回收此时占用的内存,故每次放入新的对象前,先判断此队列是否有值,若有,主动释放所占用的内存空间
/** * 员工信息类 */ public class Employee { private String id ; // 主键 private String name ; // 姓名 private String department ; // 部门 private Double salary ; // 工资 public Employee(String id){ this.id = id ; } public Employee(String id, String name, String department, Double salary) { super(); this.id = id; this.name = name; this.department = department; this.salary = salary; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } @Override public String toString() { return "Employee [id=" + id + ", name=" + name + ", department=" + department + ", salary=" + salary + "]"; } }
import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.util.Hashtable; /** * 员工信息缓存 */ public class EmployeeCache { // 单例模式:懒汉式 private static EmployeeCache employeeCache ; private EmployeeCache(){ // 构造缓存对象时,初始化缓存容器、软索引队列 cache = new Hashtable<String, EmployeeCache.EmployeeRef>(); queue = new ReferenceQueue<Employee>(); } public synchronized static EmployeeCache getInstance(){ if(null == employeeCache){ employeeCache = new EmployeeCache(); } return employeeCache; } // 缓存容器 private static Hashtable<String,EmployeeRef> cache = null; // 软索引队列 private static ReferenceQueue<Employee> queue = null ; /** * 私有内部类:Employee 的软索引对象 */ private class EmployeeRef extends SoftReference<Employee>{ private String uniqueKey = ""; public EmployeeRef(Employee referent, ReferenceQueue<? super Employee> q) { super(referent, q); this.setUniqueKey(referent.getId()); } public void setUniqueKey(String uniqueKey) { this.uniqueKey = uniqueKey; } } /** * 向缓存中添加元素 */ public void put(Employee employee){ // 清空已在引用队列中的软索引对象,释放空间 clearReferenceQueue(); EmployeeRef ref = new EmployeeRef(employee, queue); cache.put(ref.uniqueKey, ref); } private void clearReferenceQueue(){ EmployeeRef ref = null ; // 引用队列中的数据出队列 while((ref = (EmployeeRef)queue.poll()) != null){ // 同时清除该软引用作为KEY的对象内容 cache.remove(ref.uniqueKey); } } /** * 从缓存中取出元素 * @param key * @return */ public Employee get(String key){ Employee employee = null ; if(cache.containsKey(key)){ EmployeeRef employeeRef = cache.get(key); employee = employeeRef.get(); } if(null == employee){ employee = new Employee(key); EmployeeRef ref = new EmployeeRef(employee, queue); cache.put(key, ref); } return employee ; } }
public class EmployeeCacheMain { private static EmployeeCache cache = EmployeeCache.getInstance(); /** * @param args */ public static void main(String[] args) { Employee e1 = new Employee("1", "张三", "测试部门", 10000.0); Employee e2 = new Employee("2", "李四", "开发部门", 15000.0); cache.put(e1); cache.put(e2); Employee employee = cache.get("1"); System.out.println(employee.toString()); e2.setDepartment("测试部门"); cache.put(e2); System.out.println(cache.get("2").getDepartment()); } }
博文参考:
java引用类型
浅谈java对象引用及对象赋值
发表评论
-
JSP自定义标签
2017-11-14 20:35 342JSP页面中分页功能实现使用了 <urlChange ... -
手机号码替换中间四位
2017-10-24 21:41 920需求描述: 为用户隐私考虑,展示用户信息时需要将中间用*代替 ... -
遍历集合删除元素
2017-10-24 18:44 657一、根据下标删除元素 1.测试代码 ArrayLis ... -
统计每天的数据
2017-10-10 21:23 543需求:按天统计数据 分析:create_time 为 dat ... -
基于AbstractDataSource实现主从数据库切换
2017-10-07 18:03 1043基于AbstractDataSource实现主从数据库切换 ... -
服务器文件下载
2016-03-27 09:53 377项目需求:在列表页面上提供文件下载链接 项目实现: 1.准 ... -
扫码登录功能实现
2015-08-21 08:19 518需求:PC端(电脑端) ... -
基于SHIRO实现用户登陆后跳转其匿名访问的URL路径
2015-07-15 15:03 3642需求描述: 用户在未登录时访问网站中某个需要登录后才能访问 ... -
基于SHIRO的管理后台权限认证系统实现(一)
2015-07-09 10:05 7006基于SHIRO的管理后台权限认证系统实现(一) 一、项目需求 ... -
基于SHIRO的管理后台权限认证系统实现(二)
2015-06-28 10:14 817用户登陆系统后左侧菜单加载 项目:管理员系统 功能:用户登 ... -
Velocity中set的使用
2015-05-26 10:46 531问题:从页面接收某字段的提交数据,数据要求是组合后的编号 ... -
Velocity页面中输出时间年月
2015-05-19 20:52 994问题:注册页面要求有创建时间的选项添加,年为至今为止 实现: ... -
Set判重操作实现
2015-05-15 15:28 800需求:Set<Po>判重操作实现 问题:Set& ... -
如何去除List集合中的重复数据
2015-05-15 13:12 911需求:用户权限查看, ... -
Date相关功能实现
2015-05-12 19:47 628一、同一天 需求:用户记录跟踪列表展示,要求用户数据同一天内 ... -
velocity截取过长的字段值
2015-05-11 20:06 378问题:页面列表展示时,某个字段的值超长,影响页面的整体样式 ... -
将list中某个元素放在首位
2015-05-10 17:25 4578需求:程序开发过程中,业务方要求在展示国家列表时要将US放在首 ... -
Velocity遍历map与遍历list
2015-04-22 20:16 6944问题: 向页面传递key与value的组合 1. 1.1 ...
相关推荐
**使用软引用构建敏感数据缓存的示例** 在内存敏感的应用场景中,如雇员信息查询系统,使用软引用可以有效地平衡内存使用和性能。通过创建软引用对象来存储最近访问的雇员信息,当内存不足时,这些软引用对象会被...
**软引用构建敏感数据缓存**: 在设计系统时,如雇员信息查询系统,使用软引用可以创建一个内存敏感的缓存。当内存充足时,最近访问过的雇员信息可以保留在缓存中,提高查询效率。而当内存不足时,这些信息作为软...
在Android开发中,为了优化应用程序性能...理解并合理使用这些引用类型,对于构建高效、健壮的Android应用至关重要。在图片缓存场景中,结合软引用和弱引用,可以在保证性能的同时,避免内存泄漏,提供更好的用户体验。
总结,`Android_ImageCache` 关注的是如何在Android平台上构建一个完整的图片缓存系统,结合了内存缓存、软引用、文件缓存和网络下载等技术,以优化图片加载性能,提高应用的响应速度和用户体验。开发者在实际项目中...
1. **软引用(Soft Reference)**:软引用通常用于实现内存敏感的缓存。当系统内存不足时,垃圾收集器会回收软引用指向的对象,以防止系统出现OutOfMemoryError。在回收前,软引用可以被用来检查对象是否还存在。 2...
4. **Soft References & Weak References**:Java中的软引用和弱引用可以帮助实现内存敏感的缓存策略。 ### 五、缓存的并发控制与同步 在多线程环境下,缓存的并发控制至关重要。Java的`synchronized`关键字、`...
这些引用提供了访问ORM框架所需的所有类型和方法,使得我们可以构建、查询和管理数据模型。 6. **性能考虑**:虽然ORM简化了数据库操作,但它可能会带来一定的性能开销,如额外的内存消耗和查询转换时间。因此,在...
总结起来,"NHibernate.rar所有需要添加的引用功能包" 提供了 NHibernate ORM 框架的完整依赖,包括 NHibernate 核心、日志记录、动态代理和特殊集合类型,这些是构建基于 NHibernate 的数据访问层所必需的。...
11.3 数据缓存 11.3.1 向缓存添加项目 11.3.2 简单的缓存测试 11.3.3 缓存优先级 11.3.4 使用数据源控件的缓存 11.4 缓存依赖 11.4.1 文件和缓存项目依赖 11.4.2 聚合依赖 11.4.3 移除项目回调 ...
- **数据加密**:集成加密机制以保护敏感数据的安全性。 - **异常处理**:设计一致的策略来管理在不同架构层中出现的异常。 - **日志记录**:通过内置的日志记录工具或自定义提供程序实现系统日志记录。 - **验证...
1. 数据混淆:自定义字体可以用来显示一些敏感数据,如订单号、验证码等。这些数据在源代码中以普通文本形式存在,但通过自定义字体渲染后,采集工具无法正确解析,从而达到防采集的目的。 2. 字体映射:可以创建一...
这个项目“web服务的建立和引用——模拟网上购物”旨在通过实例演示如何构建和使用Web服务来模拟一个简单的网上购物系统。在这个过程中,我们将重点讨论ASP.NET Web服务的使用,这是一种由微软提供的强大工具,用于...
- **安全性**:确保对敏感数据进行加密,避免跨站脚本攻击(XSS)和跨站请求伪造(CSRF)。 - **异常处理**:在服务器端妥善处理异常,避免暴露过多的系统信息给用户。 总结,AjaxPro.DLL为ASP.NET开发者提供了一种简单...
11.3 数据缓存 373 11.3.1 向缓存添加项目 373 11.3.2 简单的缓存测试 375 11.3.3 缓存优先级 376 11.3.4 使用数据源控件的缓存 376 11.4 缓存依赖 379 11.4.1 文件和缓存项目依赖 379 11.4.2 聚合...
4. 内存管理:注意内存泄漏,避免对象冗余,合理使用软引用和弱引用。 五、安全性考虑 1. 数据加密:敏感信息如用户密码、订单详情等需进行加密传输和存储。 2. 权限管理:遵循最小权限原则,只申请必要的系统权限...
9. **数据加密**:对敏感数据进行加密,如使用AES、RSA等加密算法,保护用户隐私和应用安全。 **二、拓展 ADK (Android Development Kit)** 1. **动态加载方案**:实现动态加载可以减少应用安装包大小,如使用Dex...
5. **内存管理**:避免内存泄漏,及时释放不再使用的对象,合理使用软引用和弱引用。使用`Activity`的`onSaveInstanceState()`和`onRestoreInstanceState()`方法保存和恢复用户界面的状态。 6. **异步操作**:避免...
- **加密传输**:对敏感数据进行加密处理,防止中途截获。 - **备份与恢复计划**:制定详尽的数据备份方案,确保数据安全。 通过以上内容的学习,我们可以了解到SAS ETL不仅是一种工具,更是一种实现数据价值的重要...