我正在浏览一些旧书,并找到了Peter Hagger的"Practical Java".在性能部分,建议将对象引用设置为null不再需要时.
在Java中,设置对象引用是为了null提高性能还是垃圾回收效率?如果是这样,在什么情况下这是一个问题?容器类?对象组成?匿名内部课程?
我经常在代码中看到这个.这是现在过时的编程建议还是仍然有用?
我想删除我创建的对象(跟随你的椭圆),但是我该怎么做呢?
delete follower1;
Run Code Online (Sandbox Code Playgroud)
没用.
编辑:
好的,我会给出更多背景信息.我正在制作一个你可以控制的椭圆形游戏,还有一个跟随你的椭圆形游戏.现在我有了名为:DrawPanel.class的文件,这个类在屏幕上绘制所有内容,并处理碰撞,声音等.我有一个enemy.class,它是玩家之后的椭圆形.我有一个entity.class,这是你可以控制的玩家.如果玩家与追随者相交,我希望我的玩家对象被删除.我这样做的方式:
public void checkCollisions(){
if(player.getBounds().intersects(follower1.getBounds())){
Follower1Alive = false;
player.health = player.health - 10;
}
}
Run Code Online (Sandbox Code Playgroud) 当我删除for循环时,我得到一个OutOfMemoryError.当我使用for循环时,我没有得到错误.任何人都可以帮助我理解这种行为吗?
public class JavaMemoryPuzzlePolite {
private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);
public void f() {
{
System.out.println(dataSize);
byte[] data = new byte[dataSize];
}
for (int i = 0; i < 1; i++) {
System.out.println("Please be so kind and release memory");
}
System.out.println(dataSize);
byte[] data2 = new byte[dataSize];
}
public static void main(String[] args) {
JavaMemoryPuzzlePolite jmp = new JavaMemoryPuzzlePolite();
jmp.f();
}
}
Run Code Online (Sandbox Code Playgroud) 我们最近将我们的消息处理应用程序从Java 7升级到Java 8.自升级以来,我们偶尔会遇到一个流在读取时被关闭的异常.记录显示终结器线程正在调用finalize()保存流的对象(进而关闭流).
代码的基本概要如下:
MIMEWriter writer = new MIMEWriter( out );
in = new InflaterInputStream( databaseBlobInputStream );
MIMEBodyPart attachmentPart = new MIMEBodyPart( in );
writer.writePart( attachmentPart );
Run Code Online (Sandbox Code Playgroud)
MIMEWriter并且MIMEBodyPart是本土MIME/HTTP库的一部分. MIMEBodyPart扩展HTTPMessage,具有以下内容:
public void close() throws IOException
{
if ( m_stream != null )
{
m_stream.close();
}
}
protected void finalize()
{
try
{
close();
}
catch ( final Exception ignored ) { }
}
Run Code Online (Sandbox Code Playgroud)
异常发生在调用链中MIMEWriter.writePart,如下所示:
MIMEWriter.writePart() 写入部件的标题,然后调用 part.writeBodyPartContent( this )MIMEBodyPart.writeBodyPartContent()调用我们的实用工具方法 …如何优化具有大量(数百万)长寿命对象的应用程序的堆大小使用?(大缓存,从数据库加载大量记录)
我正在寻找通用编程或Java特定的答案.没有时髦的编译器开关.
编辑:
优化POJO的内存表示,它可以在堆中出现数百万次.
用例
简历回复:
我有这样的场景:
public void processData(String name,String value) {
/* line 1 */ MyDTO dto = new MyDTO();
/* line 2 */ dto.setName(name);
/* line 3 */ dto.setValue(value);
/* line 4 */ sendThroughJMSChannel(dto);
/* line 5 */ dto = null; //As a best practice, should I do this ?
}
Run Code Online (Sandbox Code Playgroud)
在第4行之后的程序中,我不需要dto进一步处理.作为最佳实践,我应该设置dto到null在第5行,或者忽略它?
通过设置它null,我期待快速垃圾收集.这是对的吗?
好吧,我开发了一个使用多个对象关系的java应用程序,这使得内存使用过于昂贵.我没有管理java内存的经验,因为应用程序设计很难破坏对象并重新利用先前清除的空间.例如,我正在使用Observer和MVC模式.
所以,理论说......
如果从任何活动线程或任何静态引用无法访问对象,则该对象符合垃圾收集或GC的条件
换句话说,如果对象的所有引用都为null,则可以说对象符合垃圾回收的条件.
但是,在我的短暂经历中,当我有一个像我一样的场景,你不知道如何销毁我想要从内存中删除的对象(例如,当一个框架关闭时)时,我很难破坏所有引用存在许多对类的引用.
根据这个上下文,当有多个引用时,如何处理对象破坏?或者当你有一个复杂的参考对象时,我怎么需要管理内存?
所以我目前正在开发一个程序,它需要能够处理存储在数组中的大量数据,并且需要一种方法来清除数组中的所有内容.对于下面的例子,做记忆明智会是一件坏事吗?我知道垃圾收集器最终会为你清理它,但有没有理由为什么另一个方法(例如for循环并将每个值设置为null)可能比这更好?
Object[] objArray = new Object[n];
/*Do some stuff with objArray*/
objArray = new Object[n]
Run Code Online (Sandbox Code Playgroud)
否则,执行此操作将允许此操作在O(1)时间内运行,而for循环将采用O(n).
这个问题是我之前提出的问题答案的结果.
我被要求使用Eclipse MAT来调查吃掉堆的东西.以下是我的观察(热门消费者):
class sun.awt.SunToolkit 333.7 MB
com.tennisearth.service.impl.CacheManagerServiceImpl 136 MB
org.apache.jasper.servlet.JspServlet 91.5 MB
Run Code Online (Sandbox Code Playgroud)
我已经解决了这个问题CacheManageServiceImpl,但需要帮助SunToolkit.
下面是创建Image对象的代码(内部使用SunToolkit.imgCache)
Image img = new ImageIcon(imagePath).getImage();
int imageWidth = img.getWidth(null);
int imageHeight = img.getHeight(null);
Run Code Online (Sandbox Code Playgroud)
Plz注意,仅创建Image对象以获取图像的宽度/高度,稍后在某些逻辑中需要该宽度/高度.
有没有办法禁用SunToolkit图像缓存?更好的是,有没有办法清除这个缓存?或者有更好的方法可以检索这些信息吗?
BTW供您参考,我使用下面的命令来运行jboss(请注意堆大小参数):
java -Dprogram.name=run.sh -server -Xms256m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=256m -verbose:gc -Xloggc:/data1/logs/jboss/GC.log -XX:+HeapDumpOnOutOfMemoryError -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Dorg.apache.catalina.STRICT_SERVLET_COMPLIANCE=false -Djava.net.preferIPv4Stack=true -Djava.library.path=/usr/local/java/jboss-4.2.2.GA/bin/native -Djava.endorsed.dirs=/usr/local/java/jboss-4.2.2.GA/lib/endorsed -classpath /usr/local/java/jboss-4.2.2.GA/bin/run.jar:/usr/local/java/jdk1.6.0_06/lib/tools.jar org.jboss.Main -c default -b <IP_ADDRESS> -Djboss.messaging.ServerPeerID=1
Run Code Online (Sandbox Code Playgroud)
萨米特
有人最近向我建议,为了避免占用内存,Java应用程序应始终在可能的情况下(通过将其设置为null)销毁此方法结束时在方法中创建的所有对象.
我之前没有经常这样做,从我的观点来看,它似乎首先打败了垃圾收集器的目的.当这个策略有用时,是否有任何指导/推理?如果你小心对象,你有没有必要面对申请?
java ×10
caching ×2
memory ×2
arrays ×1
big-o ×1
coding-style ×1
finalize ×1
finalizer ×1
heap ×1
image ×1
java-8 ×1
jvm ×1
objectpool ×1
performance ×1