java优化占用内存的方法

信创迁移实战:在银河麒麟V10-SP1上为Milvus离线部署Docker(附SP1专属避坑指南) 本文详细介绍了在银河麒麟V10-SP1 x86_64环境下离线部署Docker的全流程,特别针对该版本特有的自定义目录安装失败问题提供深度分析和解决方案。通过实战验证的步骤和避坑指南,帮助用户在信创项目中顺利完成Milvus等应用的容器化部署。 阅读详情

原文出自【雪的痕迹】
原文地址:http://www.java3z.com/cwbwebhome/article/article8/852.html

java做的系统给人的印象是什么?占内存!说道这句话就会有N多人站出来为java辩护,并举出一堆的性能测试报告来证明这一点。其实从理论上来讲java做的系统并不比其他语言开发出来的系统更占用内存,那么为什么却有这么N多理由来证明它确实占内存呢?两个字,陋习。

(1)别用new Boolean()
在很多场景中Boolean类型是必须的,比如JDBC中boolean类型的set与get都是通过Boolean封装传递的,大部分ORM也是用Boolean来封装boolean类型的,比如:

ps.setBoolean("isClosed",new Boolean(true));
ps.setBoolean("isClosed",new Boolean(isClosed));
ps.setBoolean("isClosed",new Boolean(i==3));

通常这些系统中构造的Boolean实例的个数是相当多的,所以系统中充满了大量Boolean实例小对象,这是相当消耗内存的。Boolean类实际上只要两个实例就够了,一个true的实例,一个false的实例。

Boolean类提供两了个静态变量:
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

需要的时候只要取这两个变量就可以了,
比如:
ps.setBoolean("isClosed",Boolean.TRUE);
那么象2、3句那样要根据一个boolean变量来创建一个Boolean怎么办呢?可以使用Boolean提供的静态方法: 
Boolean.valueOf()

比如:
ps.setBoolean("isClosed",Boolean.valueOf(isClosed));
ps.setBoolean("isClosed",Boolean.valueOf(i==3));

因为valueOf的内部实现是:return (b ? TRUE : FALSE);
所以可以节省大量内存。相信如果Java规范直接把Boolean的构造函数规定成private,就再也不会出现这种情况了。

(2)别用new Integer
和Boolean类似,java开发中使用Integer封装int的场合也非常多,并且通常用int表示的数值通常都非常小。SUN 
SDK中对Integer的实例化进行了优化,Integer类缓存了-128到127这256个状态的Integer,如果使用Integer.valueOf(int 
i),传入的int范围正好在此内,就返回静态实例。这样如果我们使用Integer.valueOf代替new 
Integer的话也将大大降低内存的占用。如果您的系统要在不同的SDK(比如IBM 
SDK)中使用的话,那么可以自己做了工具类封装一下,比如IntegerUtils.valueOf(),这样就可以在任何SDK中都可以使用这种特性。

(3)用StringBuffer代替字符串相加
这个我就不多讲了,因为已经被人讲过N次了。我只想将一个不是笑话的笑话,我在看国内某“著名”java开发的WEB系统的源码中,竟然发现其中大量的使用字符串相加,一个拼装SQL语句的方法中竟然最多构造了将近100个string实例。无语中!

(4)过滥使用哈希表
有一定开发经验的开发人员经常会使用hash表(hash表在JDK中的一个实现就是HashMap)来缓存一些数据,从而提高系统的运行速度。比如使用HashMap缓存一些物料信息、人员信息等基础资料,这在提高系统速度的同时也加大了系统的内存占用,特别是当缓存的资料比较多的时候。其实我们可以使用操作系统中的缓存的概念来解决这个问题,也就是给被缓存的分配一个一定大小的缓存容器,按照一定的算法淘汰不需要继续缓存的对象,这样一方面会因为进行了对象缓存而提高了系统的运行效率,同时由于缓存容器不是无限制扩大,从而也减少了系统的内存占用。现在有很多开源的缓存实现项目,比如ehcache、oscache等,这些项目都实现了FIFO、MRU等常见的缓存算法。

(5)避免过深的类层次结构和过深的方法调用
因为这两者都是非常占用内存的(特别是方法调用更是堆栈空间的消耗大户)。

(6)变量只有在用到它的时候才定义和实例化。

(7)尽量避免使用static变量
类内私有常量可以用final来代替。 

java内存管理的思想(主要来源于thinking in java)

Java内存管理特点
Java一个最大的优点就是取消了指针,由垃圾收集器来自动管理内存的回收。程序员不需要通过调用函数来释放内存。


1、Java的内存管理就是对象的分配和释放问题。
在Java中,程序员需要通过关键字new为每个对象申请内存空间 
(基本类型除外),所有的对象都在堆 
(Heap)中分配空间。
对象的释放是由GC决定和执行的。
在Java中,内存的分配是由程序完成的,而内存的释放是由GC完成的,这种收支两条线的方法简化了程序员的工作。但也加重了JVM的工作。这也是Java程序运行速度较慢的原因之一。

GC释放空间方法:
监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等。当该对象不再被引用时,释放对象。


2、内存管理结构
Java使用有向图的方式进行内存管理,对于程序的每一个时刻,我们都有一个有向图表示JVM的内存分配情况。

将对象考虑为有向图的顶点,将引用关系考虑为图的有向边,有向边从引用者指向被引对象。另外,每个线程对象可以作为一个图的起始顶点,例如大多程序从main进程开始执行,那么该图就是以main进程顶点开始的一棵根树。在这个有向图中,根顶点可达的对象都是有效对象,GC将不回收这些对象。如果某个对象 
(连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被GC回收。 

3、使用有向图方式管理内存的优缺点
Java使用有向图的方式进行内存管理,可以消除引用循环的问题,例如有三个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的。
这种方式的优点是管理内存的精度很高,但是效率较低。


++:
另外一种常用的内存管理技术是使用计数器,例如COM模型采用计数器方式管理构件,它与有向图相比,精度行低(很难处理循环引用的问题),但执行效率很高。


★ Java的内存泄露
Java虽然由GC来回收内存,但也是存在泄露问题的,只是比C++小一点。


1、与C++的比较
c++所有对象的分配和回收都需要由用户来管理。即需要管理点,也需要管理边。若存在不可达的点,无法回收分配给那个点的内存,导致内存泄露。存在无用的对象引用,自然也会导致内存泄露。
Java由GC来管理内存回收,GC将回收不可达的对象占用的内存空间。所以,Java需要考虑的内存泄露问题主要是那些被引用但无用的对象——即指要管理边就可以。被引用但无用的对象,程序引用了该对象,但后续不会再使用它。它占用的内存空间就浪费了。
如果存在对象的引用,这个对象就被定义为“活动的”,同时不会被释放。


2、Java内存泄露处理
处理Java的内存泄露问题:确认该对象不再会被使用。
典型的做法——
把对象数据成员设为null
从集合中移除该对象
注意,当局部变量不需要时,不需明显的设为null,因为一个方法执行完毕时,这些引用会自动被清理。


例子:
List myList=new ArrayList();
for (int i=1;i<100; i++) {
    Object o=new 
    Object();
    myList.add(o);
    o=null;
}
//此时,所有的Object对象都没有被释放,因为变量myList引用这些对象。

当myList后来不再用到,将之设为null,释放所有它引用的对象。之后GC便会回收这些对象占用的内存。


★ 对GC操作
对GC的操作并不一定能达到管理内存的效果。

GC对于程序员来说基本是透明的,不可见的。我们只有几个函数可以访问GC,例如运行GC的函数System.gc(),System.。
但是根据Java语言规范定义, 
System.gc()函数不保证JVM的垃圾收集器一定会执行。因为,不同的JVM实现者可能使用不同的算法管理GC。通常,GC的线程的优先级别较低。

JVM调用GC的策略有很多种,有的是内存使用到达一定程度时,GC才开始工作,也有定时执行的,有的是平缓执行GC,有的是中断式执行GC。但通常来说,我们不需要关心这些。除非在一些特定的场合,GC的执行影响应用程序的性能,例如对于基于Web的实时系统,如网络游戏等,用户不希望GC突然中断应用程序执行而进行垃圾回收,那么我们需要调整GC的参数,让GC能够通过平缓的方式释放内存,例如将垃圾回收分解为一系列的小步骤执行,Sun提供的HotSpot 
JVM就支持这一特性。


★ 内存泄露检测
市场上已有几种专业检查Java内存泄漏的工具,它们的基本工作原理大同小异,都是通过监测Java程序运行时,所有对象的申请、释放等动作,将内存管理的所有信息进行统计、分析、可视化。开发人员将根据这些信息判断程序是否有内存泄漏问题。这些工具包括Optimizeit 
Profiler,JProbe Profiler,JinSight , Rational 公司的Purify等。

在运行过程中,我们可以随时观察内存的使用情况,通过这种方式,我们可以很快找到那些长期不被释放,并且不再使用的对象。我们通过检查这些对象的生存周期,确认其是否为内存泄露。


★ 软引用
特点:只有当内存不够的时候才回收这类内存,同时又保证在Java抛出OutOfMemory异常之前,被设置为null。
保证最大限度的使用内存而不引起OutOfMemory异常。
在某些时候对软引用的使用会降低应用的运行效率与性能,例如:应用软引用的对象的初始化过程较为耗时,或者对象的状态在程序的运行过程中发生了变化,都会给重新创建对象与初始化对象带来不同程度的麻烦。


用途:

可以用于实现一些常用资源的缓存,实现Cache的功能
处理一些占用内存大而且声明周期较长,但使用并不频繁的对象时应尽量应用该技术


★ java程序设计中有关内存管理的经验

1.最基本的建议是尽早释放无用对象的引用。如:...
A a = new A();
//应用a对象
a = null; //当使用对象a之后主动将其设置为空
….
注:如果a 是方法的返回值,不要做这样的处理,否则你从该方法中得到的返回值永远为空,而且这种错误不易被发现、排除 
2.尽量少用finalize函数。它会加大GC的工作量。
3.如果需要使用经常用到的图片,可以使用soft应用类型。它尽可能把图片保存在内存中
4.注意集合数据类型,包括数组、树、图、链表等数据结构,这些数据结构对GC来说,回收更为复杂。
5.尽量避免在类的默认构造器中创建、初始化大量的对象,防止在调用其自类的构造器时造成不必要的内存资源浪费
6.尽量避免强制系统做垃圾内8.尽量做远程方法调用类应用开发时使用瞬间值变量,除非远程调用端需要获取该瞬间值变量的值。
9.尽量在合适的场景下使用对象池技术以提高系统性能。存的回收,增长系统做垃圾回收的最终时间
7.尽量避免显式申请数组空间

Mamba-YOLOv8深度解析:基于状态空间模型的下一代目标检测架构(含完整代码与实战部署)文末含资料链接! 通过本文的完整指南,您将掌握从理论创新到工程落地的全流程技术细节。立即动手实践,开启目标检测的新纪元! 阅读详情

相关推荐

xilinx vivado 设置多核多线程加快综合、布局布线、仿真速度的方法

加快vivado布局布线速度的多核编译方法 在tcl中执行下面的语句 set param general.maxThreads n来设置,n是你的CPU线程数。 在设置之后你可以通过get_param general.maxThreads 指令来确认是否成功设置, 加快vivado综合速度的多核编译方法 操作方法与上面加快布局布线的方法一样。 实际发现效果并不是很明显,官方论坛中提到只有在LINUX上才能发挥8核以上的效能,而且8核以上的效能提升并不明显。 加快vivado仿真.

shawn的FPGA圈 2万+

java优化占用内存的方法一

(转)java做的系统给人的印象是什么?占内存!说道这句话就会有N多人站出来为java辩护,并举出一堆的性能测试报告来证明这一点。其实从理论上来讲java做的系统并不比其他语言开发出来的系统更占用内存,那么为什么却有这么N多理由来证明它确实占内存呢?两个字,陋习。 (1)别用new Boolean() 在很多场景中Boolean类型是必须的,比如JDBC中boolean类型的set与get...

jieke541623的专栏 313

在 NVIDIA Orin (JetPack 6.0) 上配置 PyTorch 2.4 + Torchvision 0.19 的完整避坑指南

本文提供在NVIDIA Jetson Orin设备上,基于JetPack 6.0系统配置PyTorch 2.4与Torchvision 0.19环境的完整指南。通过使用Miniconda环境隔离、安装特定版本PyTorch夜间构建版、编译匹配的Torchvision源码等步骤,解决版本不匹配、CUDA支持等常见问题,确保AI开发环境稳定可用。

weixin_29179311的博客 365

Java进程占用内存超高分析

Java进程占用内存超高分析_1. 报错如下图2. 解决办法3. 我用到的解决方法 写了一个Java服务,没有定时服务,没有线程池,没有重度的读写,只是对外提供了几个接口,接口的访问量并不高,结果占用内存一会就会飙升到80%+; 1. 报错如下图 2. 解决办法 jmap这篇文章写的很细致,可以大致浏览看一下 jvm调优_java jvm 参数 -Xms -Xmx -Xmn -Xss 调优 java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -Xmx3550

qq_40985985的博客 1135

密码学:一文看懂Base64算法

Base64常常在我们开发中出现,我们可能只知道它是一串乱码(看不懂的符号),知道有时候知道我们需要把一些数据进行base64编码,有时候需要进行Base64解码。但是却不知道它的作用是什么?它存在的意义是什么?还有它是如何生成的?如何编码和解码?上述的疑问相信在你读完本篇文章之后烟消云散。下面开始正文。Base64是什么?它和加密解密操作有什么关系吗?没错,这就是经过Base64编码后的字符串。对它解码后,我们获得以下内容点个关注,是对我持续创作的最大的鼓励!

Shujie 1万+

【ChangeCLIP】Remote sensing change detection with multimodal vision-language representation learning

ChangeCLIP论文及代码使用详解。持续更新变化检测最新论文,欢迎订阅本专栏。

向上生长的程序媛的博客 1338

Java进程占用内存过高,排查解决方法

最近收到邮件报警,说内存使作率达到84%。如下图: 解决方法: A:可能是代码原因导致的问题: 1、使用命令:top查看当前进程的状态 2、从上图可以看到PID:916的java进程占用内存较大。定位线程问题(通过命令查看PID 为25894 进程的线程情况),命令:# ps p 916 -L -o pcpu,pmem,pid,tid,time,tname,cmd ...

weixin_30323961的博客 5万+

外骨骼机器人(二):自适应振荡器

振荡器是一种数学工具,可以用于实时跟踪、预测类周期信号的频率、相位、幅值等,而助行外骨骼机器人需要自动适应人体的行走频率、幅度,两者相结合,就能使助行外骨骼机器人拥有更舒适、更自然的行走步态。 ......

行者无疆的博客 4264

java在程序中cd怎么_Java 程序该怎么优化?工具篇

程序员:为什么程序总是那么慢?时间都花到哪里去了?面试官:若你写的 Java 程序,出现了性能问题,该怎么去排查呢?工欲善其事必先利其器,为你呈上一箩筐性能优化工具,必有一款满足你,废话不多说,直奔主题。1. hprof 工具hprof 工具是通过织入监控代码,来对 Java 程序进行监控的一款工具。可以监控 Java 程序在运行时占用的 CPU,及统计堆内存使用等。例如:每隔 10 毫秒采样 C...

weixin_30037665的博客 440

车载以太网:PHY(物理层)介绍

本文以TJA1101芯片为实例介绍了车载以太网PHY(物理层)组成。

kevin1499的博客 6231

我的GIT练习ONE

Git 是一个分布式版本控制及源代码管理工具;Git 可以为你的项目保存若干快照,以此来对整个项目进行版本管理每一次的练习,都是对自身知识的巩固,以及对自身知识的一个测试。

是个非常热爱生活、乐观、奋斗、努力的逗比青年 8871

2G内存的极限优化,为Java开发插上飞翔的翅膀

Java开发在所有的开发中,属于对系统要求比较高的一个了。而随着硬件性能的逐步提升并伴随着价格的大幅度降价,现在的Java开发人员相信都有了个比较适宜的开发环境了。好的开发环境是我们高效工作的一个有效保障,但如何最优化当前的硬件配置进一步提升性能,则需要每个人根据自己的习惯进行进一步的优化。 本人的硬件配置是IBM T60,CPU: T5600 Core Duo 2 1.83G,内存:2G

Eric Zhu的专栏 2555

“华为杯”研究生数学建模竞赛2017年-【华为杯】B题:面向下一代光通信的 VCSEL 激光器仿真模型

得出以下主要结论:在相同的偏置电流条件下,随着温度的升高,带宽的峰值向。在相同的温度下,随着电流的增大,带宽的峰值越小且曲线由波峰形状。方案,包括可能的数学公式,不同温度和偏置电流下的带宽响应曲线,并与问题。线,得出以下主要结论:在相同的偏置电流条件下,随着温度的升高,带宽的峰。在相同的温度下,随着电流的增大,带宽的峰值越小且曲线由波峰形状逐渐变得。得的激光器特性曲线和模型中仿真得到的特性曲线,之后,可以将两组曲线的差。说明的是,由于数值优化算法的成功与否很大程度上依赖于初始参数的猜测,参。

getusushu的博客 99

java优化占用内存的方法(一)

java做的系统给人的印象是什么?占内存!说道这句话就会有N多人站出来为java辩护,并举出一堆的性能测试报告来证明这一点。其实从理论上来讲java做的系统并不比其他语言开发出来的系统更占用内存,那么为什么却有这么N多理由来证明它确实占内存呢?两个字,陋习。 (1)别用new Boolean()。 在很多场景中Boolean类型是必须的,比如JDBC中boolean类型的set与get都是通过

我是你是我 922

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

java优化占用内存的几种方法

java做的系统给人的印象是什么?占 内存!说道这句话就会有N多人站出来为java辩护,并举出一堆的性能测试报告来证明这一点。其实从理论上来讲java做的系统并不比其他语言开发出来的 系统更占用内存,那么为什么却有这么N多理由来证明它确实占内存呢?两个字,陋习。 (1)别用new Boolean()。 在很多场景中Boolean类型是必须的,比如JDBC中boolean类型的set与get都是通过...

qq_28286027的博客 5176

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

java优化占用内存的方法(一),java优化占用内存的方法(一)

java做的系统给人的印象是什么?占内存!说道这句话就会有N多人站出来为java辩护,并举出一堆的性能测试报告来证明这一点。其实从理论上来讲java做的系统并不比其他语言开发出来的系统更占用内存,那么为什么却有这么N多理由来证明它确实占内存呢?两个字,陋习。(1)别用new Boolean()。在很多场景中Boolean类型是必须的,比如JDBC中boolean类型的set与get都是通过Bool...

weixin_28721019的博客 363

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

java优化占用内存方法

1)new Boolean() 比如:ps.set("is_delete",new Boolean(true)); ps.set("is_delete",new Boolean(isDelete)); 在系统中构造过多的实例,所以系统中充满大量的实例对象,损耗内存。 解决办法:定义静态变量。 public static final B...

pengwei_java的博客 823

java怎么优化内存占用_java优化占用内存的方法(二)

java优化占用内存的方法(二)垃圾收集几乎是每个开发人员都喜爱的一个 Java™ 平台特性,它简化了开发,消除了所有种类的潜在代码错误。可尽管垃圾收集一般来说可以让您无需进行资源管理,有时候您还是必须自己进行一些内务处理。显式地释放资源Java 程序中使用的绝大多数资源都是对象,垃圾收集在清理对象方面做得很好。因此,您可以使用任意多的 String。垃圾收集器最终无需您的干预就会算出它们何时失效...

weixin_35761094的博客 587

java 方法占用内存_java优化占用内存的方法(二)

垃圾收集几乎是每个开发人员都喜爱的一个 Java™平台特性,它简化了开发,消除了所有种类的潜在代码错误。可尽管垃圾收集一般来说可以让您无需进行资源管理,有时候您还是必须自己进行一些内务处理。Java程序中使用的绝大多数资源都是对象,垃圾收集在清理对象方面做得很好。因此,您可以使用任意多的String。垃圾收集器最终无需您的干预就会算出它们何时失效,并收回它们使用的内存。另一方面,像文件句柄和套接字...

weixin_36018773的博客 463

java 内存优化点_JAVA进程占用高内存原因分析与优化方法

文章给各位介绍在使用JAVA时发现java进程占用高内存了,如果你也碰到这种情况我们可以参考下文来进行优化。首先看一下一个java进程的jmap输出: 代码如下 复制代码 [lex@chou ~]$ jmap -heap 837Attaching to process ID 837, please wait...Debugger attached success...

weixin_36064575的博客 1414

Java IO速度和占用内存的极致优化方法,模板方法【从hdu 2602 说起】

谈起java,给人的第一映像是什么?除了简单方便易上手,跨平台可移植,各种函数库支持类应有尽有不用重复造轮子这些特性之外,恐怕就是速度慢,占用内存高了吧。不可否认,java运行速度和内存占用方便确实无法比肩C/C++。随手举一个很直观的栗子,在ACM等其他算法竞赛中,普通给java的代码运行的时间往往都是C和C++  2~~3倍,由此可见一斑。不过我们今天要说的就是,算法效率一样的情况下,如何去优

hhczy1003的专栏 5521

京东h5st 3.1签名逆向实战:从断点调试到环境校验

在接口数据采集与前端安全研究领域,接口签名是服务端验证请求合法性的第一道门槛。以电商平台常用的 h5st 参数为例,它并非简单的时间戳拼接,而是将业务参数、设备环境、用户身份等信息经过多层编码和混淆后生成的动态密文。理解其生成原理,不仅有助于还原签名算法,更能深入认识前端加密与风控体系的整体设计。在实际逆向过程中,往往需要通过浏览器断点调试定位加密入口,结合调用栈回溯核心函数,并借助环境补全和黑盒对比验证算法逻辑。同时,签名生成后的请求频率、设备指纹、行为轨迹等维度同样影响请求成功率。本文以 h5st 3.

weixin_34183910的博客 475
上一篇: Tomcat与Jre绿色环境配置(生产环境)【参考自用】
下一篇: MySQL常见异常
码上富贵
博客等级 码龄17年 1万+粉丝 135原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值