eclipse-mosquitto / mosquitto

Eclipse Mosquitto - An open source MQTT broker
https://mosquitto.org
Other
9.1k stars 2.4k forks source link

Mosquitto can not release memory to system #2267

Open allenzt opened 3 years ago

allenzt commented 3 years ago

Hi everyone,

In my previous test, I found a strange problem, mosquitto did not release the requested memory to the system, is this a bug? any suggestions would be appreciated!

Test steps are as follows:

  1. Enabled 6 clients, each client subscribed to a topic(clean session is false), and then disconnected, record the virtual memory of mosquitto
    
    #!/usr/bin/env python3

from multiprocessing import Process import paho.mqtt.client as mqtt import time

def on_connect(client, userdata, flags, rc): print("Connected with result code" + str(rc))

def on_message(client, userdata, msg):

print("topic:" + msg.topic + " " + "mid:" + str(msg.mid) + " " + msg.payload.decode('utf-8'))

print("topic:" + msg.topic + " " + "mid:" + str(msg.mid) + "len:" + str(len(msg.payload)))
#print("topic:" + msg.topic + " " + "mid:" + str(msg.mid) + " " + msg.payload.decode('utf-8'))

def client_loop(max_client): time.sleep(1) client = mqtt.Client(str(max_client), clean_session=False)

client = mqtt.Client(str(max_client), clean_session=True)

client.on_connect = on_connect
client.on_message = on_message
client.connect("10.5.18.9", 1883, 60)
client.subscribe(f"itxpt/{max_client}", qos=1) 
print(str(max_client) + ":" + str(client))
print(str(client) + f"itxpt/{max_client}\n")
client.loop_forever()

def multiclinet_subscribe(max_client_array): processes = [Process(target=client_loop, args=(i, )) for i in max_client_array] for process in processes: process.start() for process in processes: process.join()

if name == "main": client_array = [1, 2, 3, 4, 5, 6] multiclinet_subscribe(client_array)

2. Publish 100 messages with an about 49k pyload (test file [itxpt_pin1.txt](https://github.com/eclipse/mosquitto/files/6892245/itxpt_pin1.txt))  for each of the above 6 topics 

```sh
#!/bin/bash
for i in `seq 1 6`
do
   mosquitto_pub -d -h 10.5.18.9 -p 1883 -q 1 -c -i pub -t itxpt/$i -f itxpt_pin1.txt --repeat 100 --repeat-delay 0.1
done
  1. Enabled above 6 clients to receive all messages, then check the virtual memory of mosquitto.

Environment: Test on mosquitto 1.6.13 and 2.0.11

ralight commented 3 years ago

This is a problem with long term memory usage that is very difficult to deal with. If I allocate lots of memory, then free most of the memory but not a piece of memory which is deep into the heap, the virtual memory use will remain high.

Here is an example: https://github.com/ralight/heap-allocation/blob/master/mem.c

allenzt commented 3 years ago

@ralight Thanks very much! Is there any workaround we can do to alleviate the problem ?

ralight commented 3 years ago

I really don't know, but I can't think that there is a realistic solution unfortunately.

blusewang commented 3 years ago

does virtual memory used high is better than real memory used high?