Java 对象重用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/401464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 12:14:12  来源:igfitidea点击:

Java Object Reuse

java

提问by Sid Datta

Should Java Objects be reused as often as it can be reused ? Or should we reuse it only when they are "heavyweight", ie have OS resources associated with it ?

Java 对象是否应该尽可能多地重用?或者我们应该只在它们是“重量级”时才重用它,即有与之关联的操作系统资源?

All old articles on the internet talk about object reuse and object pooling as much as possible, but I have read recent articles that say new Object()is highly optimized now ( 10 instructions ) and Object reuse is not as big a deal as it used to be.

互联网上的所有旧文章都尽可能多地谈论对象重用和对象池,但我阅读了最近的文章,说new Object()现在高度优化(10条指令)并且对象重用不像以前那么重要。

What is the current best practice and how are you people doing it ?

当前的最佳实践是什么,你们是如何做的?

采纳答案by Esko

I let the garbage collector do that kind of deciding for me, the only time I've hit heap limit with freshly allocated objects was after running a buggy recursive algorithm for a couple of seconds which generated 3 * 27 * 27... new objects as fast as it could.

我让垃圾收集器为我做这样的决定,我唯一一次用新分配的对象达到堆限制是在运行有问题的递归算法几秒钟后生成 3 * 27 * 27 ... 新对象尽可能快。

Do what's best for readability and encapsulation. Sometimes reusing objects may be useful, but generally you shouldn't worry about it.

做最有利于可读性和封装的事情。有时重用对象可能很有用,但通常您不必担心。

回答by OscarRyz

If you use them very intensivelyand the construction is costly, you should try to reuse them as much as you can.

如果你非常密集地使用它们并且建造成本很高,你应该尽可能多地重复使用它们。

If your objects are very small, and cheap to create ( like Object ) you should create new ones.

如果你的对象非常小,而且创建成本低(比如 Object ),你应该创建新的。

For instance connections database are pooled because the cost of creating a new one is higher than those of creating .. mmhh new Integer for instance.

例如连接数据库是池化的,因为创建一个新的成本高于创建 .. mmhh new Integer 的成本。

So the answer to your question is, reuse when they are heavy ANDare used often ( it is not worth to pool a 3 mb object that is only used twice )

所以回答你的问题是,当他们是沉重的,再利用经常使用(这是不值得的泳池,其只用两次3 MB的对象)

Edit:

编辑:

Additionally, this item from Effective Java:Favor Immutabilityis worth reading and may apply to your situation.

此外,来自 Effective Java: Favor Immutability 的这篇文章值得一读,可能适用于您的情况。

回答by Darron

Let the garbage collector do its job, it can be considered better than your code.

让垃圾收集器完成它的工作,它可以被认为比你的代码更好。

Unless a profiler proves it guilty. And don't even use common sense to try to figure out when it's wrong. In unusual cases even cheap objects like byte arrays are better pooled.

除非分析器证明它有罪。甚至不要用常识来试图找出什么时候出错。在不寻常的情况下,即使是像字节数组这样的廉价对象也能更好地池化。

  • Rule 1 of optimization: don't do it.
  • Rule 2 (for experts only): don't do it yet.
  • 优化规则 1:不要这样做。
  • 规则 2(仅适用于专家):先不要这样做。

回答by Thomas Morgner

Object creation is cheap, yes, but sometimes not cheap enough.

对象创建很便宜,是的,但有时不够便宜。

If you create a lot (and I mean A LOT) temporary objects in rapid succession, the costs for the garbage collector are considerable. However even with a good profiler you may not necessarily see the costs easily, as the garbage collector nowadays works in short intervals instead of blocking the whole application for a second or two.

如果你快速连续地创建很多(我的意思是很多)临时对象,垃圾收集器的成本是相当可观的。然而,即使有一个好的分析器,您也不一定很容易看到成本,因为现在垃圾收集器的工作间隔很短,而不是阻塞整个应用程序一两秒钟。

Most of the performance improvements I got in my projects came from either avoiding object creation or avoiding the whole work (including the object creation) through aggressive caching. No matter how big or small the object is, it still takes time to create it and to manage the references and heap structures for it. (And of course, the cleanup and the internal heap-defrag/copying also takes time.)

我在我的项目中获得的大部分性能改进来自避免对象创建或通过积极缓存避免整个工作(包括对象创建)。无论对象有多大或多小,创建它并管理它的引用和堆结构仍然需要时间。(当然,清理和内部堆碎片整理/复制也需要时间。)

I would not start to be religious about avoiding object creation at allcost, but if you see a jigsaw pattern in your memory-profiler, it means your garbage collector is on heavy duty. And if your garbage collector uses the CPU, the CPI is not available for your application.

我不会开始对不惜一切代价避免对象创建持虔诚态度,但是如果您在内存分析器中看到拼图模式,则意味着您的垃圾收集器正在承担重任。如果您的垃圾收集器使用 CPU,则 CPI 对您的应用程序不可用。

Regarding object pooling: Doing it right and not running into either memory leaks or invalid states or spending more time on the management than you would save is difficult. So I never used that strategy.

关于对象池:做正确的事情并且不会遇到内存泄漏或无效状态,或者在管理上花费比节省的时间更多的时间是很困难的。所以我从来没有使用过这种策略。

My strategy has been to simply strive for immutable objects. Immutable things can be cached easily and therefore help to keep the system simple.

我的策略是简单地争取不可变的对象。不可变的东西可以很容易地缓存,因此有助于保持系统简单。

However, no matter what you do: Make sure you check your hotspots with a profiler first. Premature optimization is the root of most evilness.

但是,无论您做什么:请务必先使用分析器检查热点。过早的优化是最邪恶的根源。

回答by Yuval Adam

The rule of thumb should be to use your common sense and reuse objects when their creation consumes significant resourcessuch as I/O, network traffic, DB connections, etc...

经验法则应该是使用您的常识并在创建对象消耗大量资源(例如 I/O、网络流量、数据库连接等)时重用对象...

If it's just creating a new String(), forget about the reuse, you'll gain nothing from it. Code readability has higher preference.

如果它只是创建一个 new String(),忘记重用,你将一无所获。代码可读性有更高的偏好。

回答by billybob

I would worry about performance issues if they arise. Do what makes sense first (would you do this with primatives), if you then run a profiling tool and find that it is new causing you problems, start to think about pre-allocation (ie. when your program isn't doing much work).

如果出现性能问题,我会担心。首先做有意义的事情(你会用原始人做这件事吗),如果你然后运行一个分析工具并发现它是新的给你带来问题的,开始考虑预分配(即当你的程序没有做太多工作时)。

Re-using objects sounds like a disaster waiting to happen by the way:

顺便说一下,重用对象听起来像是一场等待发生的灾难:

SomeClass someObject = new SomeClass();

someObject.doSomething();
someObject.changeState();
someObject.changeOtherState();
someObject.sendSignal();
// stuff

//re-use 
someObject.reset(); // urgh, had to put this in to support reuse
someObject.doSomethingElse(); // oh oh, this is wrong after calling changeOtherState, regardless of reset
someObject.changeState(); // crap, now this is wrong but it's not obvious yet
someObject.doImportantStuff(); // what's going on?

回答by duffymo

Object creation is certainly faster than it used to be. The newer generational GC in JDKs 5 and higher are improvements, too.

对象创建肯定比以前更快。JDK 5 及更高版本中的新一代 GC 也是改进。

I don't think either of these makes excessive creation of objects cost-free, but they do reduce the importance of object pooling. I think pooling makes sense for database connections, but I don't attempt it for my own domain objects.

我不认为这两种方法都不会免费创建过多的对象,但它们确实降低了对象池的重要性。我认为池对数据库连接有意义,但我不会为我自己的域对象尝试它。

Reuse puts a premium on thread-safety. You need to think carefully to ensure that you can reuse objects safely.

重用非常重视线程安全。您需要仔细考虑以确保可以安全地重用对象。

If I decided that object reuse was important I'd do it with products like Terracotta, Tangersol, GridGain, etc. and make sure that my server had scads of memory available to it.

如果我认为对象重用很重要,我会使用 Terracotta、Tangersol、GridGain 等产品来实现,并确保我的服务器有大量内存可用。

回答by Fortyrunner

Second the above comments.

其次是上述意见。

Don't try and second guess the GC and Hotspot. Object pooling may have been useful once but these days its not so useful unless you are talking about database connections or unique system resources.

不要尝试猜测 GC 和 Hotspot。对象池可能曾经有用过,但现在除非您在谈论数据库连接或独特的系统资源,否则它不再那么有用了。

Just try and write clean and simple code and be amazed at what Hotspot can do.

只需尝试编写干净简单的代码,就会对 Hotspot 的功能感到惊讶。

Why not use VisualVM or a profiler to take a look at your code?

为什么不使用 VisualVM 或分析器来查看您的代码?