Jump to page: 1 2
Thread overview
Extreme memory usage when `synchronized( this )` is used
May 11, 2015
tcak
May 11, 2015
tcak
May 11, 2015
Daniel Kozák
May 11, 2015
tcak
May 11, 2015
Daniel Kozák
May 11, 2015
Daniel Kozák
May 11, 2015
Daniel Kozak
May 11, 2015
tcak
May 11, 2015
tcak
May 11, 2015
Ali Çehreli
May 11, 2015
tcak
May 11, 2015
Ali Çehreli
May 11, 2015
[code]
import std.stdio;

class Connection{
	private void other() shared{}

	public void close() shared{
		synchronized( this ){
			other();
		}
	}

	public void hasData() shared{ writeln("Has Data"); }
}

void main() {
	for(long i=0; i < 250_000_000; ++i){
		auto conn = new shared Connection();

		conn.hasData();

		conn.close();
	}
}
[/code]

With this code, memory usage of program is increasing very fast. In about 10 seconds, it reached 100MB for me.

If I comment out `synchronized( this )` line with its parentheses, OR remove `(this)` from it, it suddenly turns normal. Very little memory usage.

What's happening? Is object instance being stored somewhere at each iteration?

--

I tried the same thing by creating synchronisation object instead of object itself as blow, still usage lots of memory.

[code]
import std.stdio;

class Connection{
	private Object syncObject;

	public this() shared{
		syncObject = new shared Object();
	}

	private void other() shared{}

	public void close() shared{
		synchronized( syncObject ){
			other();
		}
	}

	public void hasData() shared{ writeln("Has Data"); }
}

void main() {
	for(long i=0; i < 250_000_000; ++i){
		auto conn = new shared Connection();

		conn.hasData();

		conn.close();
	}
}
[/code]
May 11, 2015
On Monday, 11 May 2015 at 09:09:09 UTC, tcak wrote:
> [code]
> import std.stdio;
>
> class Connection{
> 	private void other() shared{}
>
> 	public void close() shared{
> 		synchronized( this ){
> 			other();
> 		}
> 	}
>
> 	public void hasData() shared{ writeln("Has Data"); }
> }
>
> void main() {
> 	for(long i=0; i < 250_000_000; ++i){
> 		auto conn = new shared Connection();
>
> 		conn.hasData();
>
> 		conn.close();
> 	}
> }
> [/code]
>
> With this code, memory usage of program is increasing very fast. In about 10 seconds, it reached 100MB for me.
>
> If I comment out `synchronized( this )` line with its parentheses, OR remove `(this)` from it, it suddenly turns normal. Very little memory usage.
>
> What's happening? Is object instance being stored somewhere at each iteration?
>
> --
>
> I tried the same thing by creating synchronisation object instead of object itself as blow, still usage lots of memory.
>
> [code]
> import std.stdio;
>
> class Connection{
> 	private Object syncObject;
>
> 	public this() shared{
> 		syncObject = new shared Object();
> 	}
>
> 	private void other() shared{}
>
> 	public void close() shared{
> 		synchronized( syncObject ){
> 			other();
> 		}
> 	}
>
> 	public void hasData() shared{ writeln("Has Data"); }
> }
>
> void main() {
> 	for(long i=0; i < 250_000_000; ++i){
> 		auto conn = new shared Connection();
>
> 		conn.hasData();
>
> 		conn.close();
> 	}
> }
> [/code]

I use DMD 2.067.1 on Ubuntu 14.04 64 bit
May 11, 2015
On Mon, 11 May 2015 09:09:07 +0000
tcak via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:

> [code]
> import std.stdio;
> 
> class Connection{
> 	private void other() shared{}
> 
> 	public void close() shared{
> 		synchronized( this ){
> 			other();
> 		}
> 	}
> 
> 	public void hasData() shared{ writeln("Has Data"); }
> }
> 
> void main() {
> 	for(long i=0; i < 250_000_000; ++i){
> 		auto conn = new shared Connection();
> 
> 		conn.hasData();
> 
> 		conn.close();
> 	}
> }
> [/code]
> 
> With this code, memory usage of program is increasing very fast. In about 10 seconds, it reached 100MB for me.
> 
> If I comment out `synchronized( this )` line with its parentheses, OR remove `(this)` from it, it suddenly turns normal. Very little memory usage.
> 
> What's happening? Is object instance being stored somewhere at each iteration?
> 
> --
> 
> I tried the same thing by creating synchronisation object instead of object itself as blow, still usage lots of memory.
> 
> [code]
> import std.stdio;
> 
> class Connection{
> 	private Object syncObject;
> 
> 	public this() shared{
> 		syncObject = new shared Object();
> 	}
> 
> 	private void other() shared{}
> 
> 	public void close() shared{
> 		synchronized( syncObject ){
> 			other();
> 		}
> 	}
> 
> 	public void hasData() shared{ writeln("Has Data"); }
> }
> 
> void main() {
> 	for(long i=0; i < 250_000_000; ++i){
> 		auto conn = new shared Connection();
> 
> 		conn.hasData();
> 
> 		conn.close();
> 	}
> }
> [/code]

I think synchronize(this) prevents GC from collect memory
May 11, 2015
On Monday, 11 May 2015 at 09:20:50 UTC, Daniel Kozák wrote:
>
> On Mon, 11 May 2015 09:09:07 +0000
> tcak via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>
>
> I think synchronize(this) prevents GC from collect memory

I am not sure whether this is expected behaviour from `synchronization` keyword.

Similar code in Java. It has settled on about 62M and didn't increase at all.

[code]
public class Main{
	private void other(){}

	public void close(){
		synchronized( this ){
			other();
		}
	}

	public void hasData(){ System.out.println("Has Data"); }

	public static void main( String[] args ){
		for(long i=0; i < 250000000; ++i){
			Main conn = new Main();

			conn.hasData();

			conn.close();

			conn = null;
		}
	}
}
[/code]
May 11, 2015
On Mon, 11 May 2015 09:40:28 +0000
tcak via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:

> On Monday, 11 May 2015 at 09:20:50 UTC, Daniel Kozák wrote:
> >
> > On Mon, 11 May 2015 09:09:07 +0000
> > tcak via Digitalmars-d-learn
> > <digitalmars-d-learn@puremagic.com> wrote:
> >
> >
> > I think synchronize(this) prevents GC from collect memory
> 
> I am not sure whether this is expected behaviour from `synchronization` keyword.
> 
> Similar code in Java. It has settled on about 62M and didn't increase at all.
> 
> [code]
> public class Main{
> 	private void other(){}
> 
> 	public void close(){
> 		synchronized( this ){
> 			other();
> 		}
> 	}
> 
> 	public void hasData(){ System.out.println("Has Data"); }
> 
> 	public static void main( String[] args ){
> 		for(long i=0; i < 250000000; ++i){
> 			Main conn = new Main();
> 
> 			conn.hasData();
> 
> 			conn.close();
> 
> 			conn = null;
> 		}
> 	}
> }
> [/code]

try destroy

void main() {
    for(long i=0; i < 250_000_000; ++i){
        auto conn = new shared Connection();

        conn.hasData();

        conn.close();
        destroy(conn);
    }
}

May 11, 2015
On Mon, 11 May 2015 09:40:28 +0000
tcak via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:

> On Monday, 11 May 2015 at 09:20:50 UTC, Daniel Kozák wrote:
> >
> > On Mon, 11 May 2015 09:09:07 +0000
> > tcak via Digitalmars-d-learn
> > <digitalmars-d-learn@puremagic.com> wrote:
> >
> >
> > I think synchronize(this) prevents GC from collect memory
> 
> I am not sure whether this is expected behaviour from `synchronization` keyword.
> 
> Similar code in Java. It has settled on about 62M and didn't increase at all.
> 
> [code]
> public class Main{
> 	private void other(){}
> 
> 	public void close(){
> 		synchronized( this ){
> 			other();
> 		}
> 	}
> 
> 	public void hasData(){ System.out.println("Has Data"); }
> 
> 	public static void main( String[] args ){
> 		for(long i=0; i < 250000000; ++i){
> 			Main conn = new Main();
> 
> 			conn.hasData();
> 
> 			conn.close();
> 
> 			conn = null;
> 		}
> 	}
> }
> [/code]

But yes I would say, it is not intentional behaviour. It should use weak reference, so It would be possible for GC to collect it. Please fill issue

May 11, 2015
On Monday, 11 May 2015 at 10:24:57 UTC, Daniel Kozák wrote:
>
> On Mon, 11 May 2015 09:40:28 +0000
> tcak via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>
>> On Monday, 11 May 2015 at 09:20:50 UTC, Daniel Kozák wrote:
>> >
>> > On Mon, 11 May 2015 09:09:07 +0000
>> > tcak via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>> >
>> >
>> > I think synchronize(this) prevents GC from collect memory
>> 
>> I am not sure whether this is expected behaviour from `synchronization` keyword.
>> 
>> Similar code in Java. It has settled on about 62M and didn't increase at all.
>> 
>> [code]
>> public class Main{
>> 	private void other(){}
>> 
>> 	public void close(){
>> 		synchronized( this ){
>> 			other();
>> 		}
>> 	}
>> 
>> 	public void hasData(){ System.out.println("Has Data"); }
>> 
>> 	public static void main( String[] args ){
>> 		for(long i=0; i < 250000000; ++i){
>> 			Main conn = new Main();
>> 
>> 			conn.hasData();
>> 
>> 			conn.close();
>> 
>> 			conn = null;
>> 		}
>> 	}
>> }
>> [/code]
>
> But yes I would say, it is not intentional behaviour. It should use
> weak reference, so It would be possible for GC to collect it. Please
> fill issue
And on 2.066.1 it works correctly, so it is a regression
May 11, 2015
On Monday, 11 May 2015 at 10:30:11 UTC, Daniel Kozak wrote:
> On Monday, 11 May 2015 at 10:24:57 UTC, Daniel Kozák wrote:
>>
>> On Mon, 11 May 2015 09:40:28 +0000
>> tcak via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>>
>>
>> But yes I would say, it is not intentional behaviour. It should use
>> weak reference, so It would be possible for GC to collect it. Please
>> fill issue
> And on 2.066.1 it works correctly, so it is a regression

I really didn't know that `destroy` would make any difference. But I made changes in my libraries. Before null'g objects, I used `destroy` as well, and memory consumption is not increasing at all. Cheers for that ;)

I think `destroy`'s behaviour should be documented much better.

If I can reach to my bugzilla account (Everytime I forget my password), I will report it now.
May 11, 2015
On Monday, 11 May 2015 at 10:48:22 UTC, tcak wrote:
> On Monday, 11 May 2015 at 10:30:11 UTC, Daniel Kozak wrote:
>> On Monday, 11 May 2015 at 10:24:57 UTC, Daniel Kozák wrote:
>>>
>>> On Mon, 11 May 2015 09:40:28 +0000
>>> tcak via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>>>
>>>
>>> But yes I would say, it is not intentional behaviour. It should use
>>> weak reference, so It would be possible for GC to collect it. Please
>>> fill issue
>> And on 2.066.1 it works correctly, so it is a regression
>
> I really didn't know that `destroy` would make any difference. But I made changes in my libraries. Before null'g objects, I used `destroy` as well, and memory consumption is not increasing at all. Cheers for that ;)
>
> I think `destroy`'s behaviour should be documented much better.
>
> If I can reach to my bugzilla account (Everytime I forget my password), I will report it now.

Reported this issue

https://issues.dlang.org/show_bug.cgi?id=14573
May 11, 2015
On 05/11/2015 03:48 AM, tcak wrote:

> I think `destroy`'s behaviour should be documented much better.

Could others tell us the missing pieces please.

Perhaps related to this discussion, the following document says "does not initiate a GC cycle or free any GC memory":

  http://dlang.org/library/object/destroy.html

Thank you,
Ali

« First   ‹ Prev
1 2