Skip to main content
Home
for DLMS smart meters
Open source solutions for DLMS smart metering

Main navigation

  • Home
  • Products
  • About us
  • Open Source
  • Community
  • Forum
  • Downloads
User account menu
  • Log in

Breadcrumb

  1. Home
  2. Forums
  3. DLMS.c Client Memory Leak In Function "com_readProfileGenericColumns"

DLMS.c Client memory leak in function "com_readProfileGenericColumns"

Forum Rules

Before commenting read Forum rules

Don't comment the topic if you have a new question.

You can create a new topic selecting correct category from Gurux Forum and then create a new topic selecting "New Topic" from the top left.

By alex_engine , 30 April, 2020
Forums
Gurux.DLMS

Hello!
When reading objects of the Generic Profile type, a memory leak of about 1 kB occurs as a result of the "com_readProfileGenericColumns" function. This leak is not fixed after calling the functions "com_readValues" and "com_readProfileGenerics". How and where can I free up occupied memory?

Profile picture for user Kurumi

Kurumi

6 years 1 month ago

Hi,

Hi,

This is no happening with our meters. Can you paste trace from received data here?
BR,
Mikko

alex_engine

6 years 1 month ago

Hi!

Hi!
debug output from meter (two asks cosem - {0, 0, 99, 98, 13 , 255}; // (gxProfileGeneric) Time correction log)

00> [COMMUNICATION]: sync_bytes {new: 35, total: 35}
00> [COMMUNICATION]: Received buf:
00> 7E A0 21 41 02 21 73 DB D8 81
00> 80 14 05 02 00 80 06 02 00 80
00> 07 04 00 00 00 01 08 04 00 00
00> 00 01 CE 6A 7E
00> [COMMUNICATION]: sync_bytes {new: 58, total: 93}
00> [COMMUNICATION]: Received buf:
00> 7E A0 38 41 02 21 30 60 4D E6
00> E7 00 61 29 A1 09 06 07 60 85
00> 74 05 08 01 01 A2 03 02 01 00
00> A3 05 A1 03 02 01 00 BE 10 04
00> 0E 08 00 06 5F 1F 04 00 00 14
00> 11 00 80 00 07 DE 86 7E
00> [COMMUNICATION]: com_initializeConnection free_ram= 16197
00> [COMMUNICATION]: com_readScalerAndUnits free_ram= 16197
00> [COMMUNICATION]: sync_bytes {new: 75, total: 168}
00> [COMMUNICATION]: Received buf:
00> 7E A0 49 41 02 21 52 C3 13 E6
00> E7 00 C4 01 81 00 01 03 02 04
00> 12 00 08 09 06 00 00 01 00 00
00> FF 0F 02 12 00 00 02 04 12 00
00> 08 09 06 00 00 01 00 01 FF 0F
00> 02 12 00 00 02 04 12 00 03 09
00> 06 00 00 60 08 00 FF 0F 02 12
00> 00 00 FB 0A 7E
00> [COMMUNICATION]: com_readProfileGenericColumns free_ram= 15173
00> [COMMUNICATION]: com_readValues free_ram= 15173
00> [COMMUNICATION]: sync_bytes {new: 24, total: 192}
00> [COMMUNICATION]: Received buf:
00> 7E A0 16 41 02 21 74 69 48 E6
00> E7 00 C4 01 81 00 06 00 00 00
00> 06 4D BA 7E
00> [COMMUNICATION]: sync_bytes {new: 24, total: 216}
00> [COMMUNICATION]: Received buf:
00> 7E A0 16 41 02 21 96 75 8C E6
00> E7 00 C4 01 81 00 06 00 00 00
00> 80 73 5B 7E
00> [COMMUNICATION]: sync_bytes {new: 54, total: 270}
00> [COMMUNICATION]: Received buf:
00> 7E A0 34 41 02 21 B8 10 32 E6
00> E7 00 C4 01 81 00 01 01 02 03
00> 19 07 D0 01 02 FF 17 36 3B FF
00> 80 00 00 19 07 D0 01 02 FF 17
00> 36 25 FF 80 00 00 06 00 02 B7
00> BB 9B 60 7E
00> [COMMUNICATION]: sync_bytes {new: 133, total: 403}
00> [COMMUNICATION]: Received buf:
00> 7E A0 83 41 02 21 DA 5C 1C E6
00> E7 00 C4 02 81 00 00 00 00 01
00> 00 6C 01 06 02 03 19 07 D0 01
00> 02 FF 17 36 3B FF 80 00 00 19
00> 07 D0 01 02 FF 17 36 25 FF 80
00> 00 00 06 00 02 B7 BB 02 03 19
00> 07 D0 01 04 FF 01 1B 00 FF 80
00> 00 00 19 07 D0 01 04 FF 01 1B
00> 00 FF 80 00 00 06 00 04 1E CD
00> 02 03 19 07 D0 01 04 FF 01 1B
00> 00 FF 80 00 00 19 07 D0 01 04
00> FF 01 1B 02 FF 80 00 00 06 00
00> 04 1E CF 02 03 19 07 D0 01 04
00> 27 FB 7E
00> [COMMUNICATION]: sync_bytes {new: 117, total: 520}
00> [COMMUNICATION]: Received buf:
00> 7E A0 73 41 02 21 FC CE C7 E6
00> E7 00 C4 02 81 FF 00 00 00 02
00> 00 5C FF 01 1B 00 FF 80 00 00
00> 19 07 D0 01 04 FF 01 1B 00 FF
00> 80 00 00 06 00 04 1E CF 02 03
00> 19 07 E4 03 17 FF 10 27 18 FF
00> 80 00 00 19 07 D0 01 06 FF 0D
00> 15 25 FF 80 00 00 06 00 07 69
00> 53 02 03 19 07 E4 04 14 FF 10
00> 0B 07 FF 80 00 00 19 07 D0 01
00> 01 FF 00 3A 2B FF 80 00 00 06
00> 00 26 4E 01 EC F8 7E
00> [COMMUNICATION]: com_readProfileGenerics free_ram= 14053
00> [COMMUNICATION]: sync_bytes {new: 35, total: 555}
00> [COMMUNICATION]: Received buf:
00> 7E A0 21 41 02 21 73 DB D8 81
00> 80 14 05 02 00 80 06 02 00 80
00> 07 04 00 00 00 01 08 04 00 00
00> 00 01 CE 6A 7E
00> [COMMUNICATION]: sync_bytes {new: 58, total: 613}
00> [COMMUNICATION]: Received buf:
00> 7E A0 38 41 02 21 30 60 4D E6
00> E7 00 61 29 A1 09 06 07 60 85
00> 74 05 08 01 01 A2 03 02 01 00
00> A3 05 A1 03 02 01 00 BE 10 04
00> 0E 08 00 06 5F 1F 04 00 00 14
00> 11 00 80 00 07 DE 86 7E
00> [COMMUNICATION]: com_initializeConnection free_ram= 15205
00> [COMMUNICATION]: com_readScalerAndUnits free_ram= 15205
00> [COMMUNICATION]: sync_bytes {new: 75, total: 688}
00> [COMMUNICATION]: Received buf:
00> 7E A0 49 41 02 21 52 C3 13 E6
00> E7 00 C4 01 81 00 01 03 02 04
00> 12 00 08 09 06 00 00 01 00 00
00> FF 0F 02 12 00 00 02 04 12 00
00> 08 09 06 00 00 01 00 01 FF 0F
00> 02 12 00 00 02 04 12 00 03 09
00> 06 00 00 60 08 00 FF 0F 02 12
00> 00 00 FB 0A 7E
00> [COMMUNICATION]: com_readProfileGenericColumns free_ram= 14693
00> [COMMUNICATION]: com_readValues free_ram= 14693
00> [COMMUNICATION]: sync_bytes {new: 24, total: 712}
00> [COMMUNICATION]: Received buf:
00> 7E A0 16 41 02 21 74 69 48 E6
00> E7 00 C4 01 81 00 06 00 00 00
00> 06 4D BA 7E
00> [COMMUNICATION]: sync_bytes {new: 24, total: 736}
00> [COMMUNICATION]: Received buf:
00> 7E A0 16 41 02 21 96 75 8C E6
00> E7 00 C4 01 81 00 06 00 00 00
00> 80 73 5B 7E
00> [COMMUNICATION]: sync_bytes {new: 54, total: 790}
00> [COMMUNICATION]: Received buf:
00> 7E A0 34 41 02 21 B8 10 32 E6
00> E7 00 C4 01 81 00 01 01 02 03
00> 19 07 D0 01 02 FF 17 36 3B FF
00> 80 00 00 19 07 D0 01 02 FF 17
00> 36 25 FF 80 00 00 06 00 02 B7
00> BB 9B 60 7E
00> [COMMUNICATION]: sync_bytes {new: 133, total: 923}
00> [COMMUNICATION]: Received buf:
00> 7E A0 83 41 02 21 DA 5C 1C E6
00> E7 00 C4 02 81 00 00 00 00 01
00> 00 6C 01 06 02 03 19 07 D0 01
00> 02 FF 17 36 3B FF 80 00 00 19
00> 07 D0 01 02 FF 17 36 25 FF 80
00> 00 00 06 00 02 B7 BB 02 03 19
00> 07 D0 01 04 FF 01 1B 00 FF 80
00> 00 00 19 07 D0 01 04 FF 01 1B
00> 00 FF 80 00 00 06 00 04 1E CD
00> 02 03 19 07 D0 01 04 FF 01 1B
00> 00 FF 80 00 00 19 07 D0 01 04
00> FF 01 1B 02 FF 80 00 00 06 00
00> 04 1E CF 02 03 19 07 D0 01 04
00> 27 FB 7E
00> [COMMUNICATION]: sync_bytes {new: 117, total: 1040}
00> [COMMUNICATION]: Received buf:
00> 7E A0 73 41 02 21 FC CE C7 E6
00> E7 00 C4 02 81 FF 00 00 00 02
00> 00 5C FF 01 1B 00 FF 80 00 00
00> 19 07 D0 01 04 FF 01 1B 00 FF
00> 80 00 00 06 00 04 1E CF 02 03
00> 19 07 E4 03 17 FF 10 27 18 FF
00> 80 00 00 19 07 D0 01 06 FF 0D
00> 15 25 FF 80 00 00 06 00 07 69
00> 53 02 03 19 07 E4 04 14 FF 10
00> 0B 07 FF 80 00 00 19 07 D0 01
00> 01 FF 00 3A 2B FF 80 00 00 06
00> 00 26 4E 01 EC F8 7E
00> [COMMUNICATION]: com_readProfileGenerics free_ram= 13581

after work com_readProfileGenericColumns free_ram is decrease and never free!

Profile picture for user Kurumi

Kurumi

6 years 1 month ago

Hi,

Hi,

This is checked and there are no memory leaks.
Can you check your source code. In the example, client calls cl_clear after all the data is collected. cl_clear calls oa_clear and it clears all COSEM objects data calling obj_clear. So all the data is clear.

If you have created profile generic object you must call obj_clear after you don't need it anymore.

Something like:

gxProfileGeneric pg;
const unsigned char ln[6] = { 0, 0, 99, 98, 13 , 255 };
cosem_init2(BASE(pg), DLMS_OBJECT_TYPE_PROFILE_GENERIC, ln);
//Read data...
//Clear the data.
obj_clear(BASE(pg));

BR,
Mikko

Profile picture for user Kurumi

Kurumi

6 years 1 month ago

Hi,

Hi,

This is checked and there are no memory leaks.
Can you check your source code. In the example, client calls cl_clear after all the data is collected. cl_clear calls oa_clear and it clears all COSEM objects data calling obj_clear. So all the data is clear.

If you have created profile generic object you must call obj_clear after you don't need it anymore.

Something like:

gxProfileGeneric pg;
const unsigned char ln[6] = { 0, 0, 99, 98, 13 , 255 };
cosem_init2(BASE(pg), DLMS_OBJECT_TYPE_PROFILE_GENERIC, ln);
//Read data...
//Clear the data.
obj_clear(BASE(pg));

BR,
Mikko

alex_engine

6 years 1 month ago

Hi!

Hi!
what does the function "com_readProfileGenericColumns" do and where does it store the data?
command "obj_clear(BASE(pg));" does not clear the memory that was occupied by this function

Profile picture for user Kurumi

Kurumi

6 years 1 month ago

Hi,

Hi,
com_readProfileGenericColumns reads capture objects from the meter.

I believe I know the reason for your problem. You haven't read the association view. If this is true, objects are not released automatically and you must release them by yourself.

I'll think if there is a generic, easier solution for this. In the meantime, you need to release objects using this method.

int obj_clearProfileGenericCaptureObjects2(gxArray* captureObjects)
{
int ret = DLMS_ERROR_CODE_OK;
int pos;
gxKey* kv;
//Objects are not cleared because client owns them and clears them later.
for (pos = 0; pos != captureObjects->size; ++pos)
{
ret = arr_getByIndex(captureObjects, pos, (void**)&kv);
if (ret != DLMS_ERROR_CODE_OK)
{
break;
}
gxfree(kv->key);
gxfree(kv->value);
}
arr_clear(captureObjects);
return ret;
}

BR,
Mikko

alex_engine

6 years 1 month ago

Thank you!

Thank you!
i add at the end of function "com_readProfileGenerics" this code:
for (int i = 0; i < objects.size; ++i)
{
if (oa_getByIndex(&objects, i, &obj) == DLMS_ERROR_CODE_OK) {
obj_clearProfileGenericCaptureObjects2(&((gxProfileGeneric*)obj)->captureObjects);
}
}

and memory clean!

Profile picture for user Kurumi

Kurumi

5 years 11 months ago

Hi,

Hi,

This is now changed. All dynamically created objects are added to dlmsSettings.releasedObjects.
You don't need to do this anymore.

BR,
Mikko

Alexander86

4 years 11 months ago

Hi!

Hi!
I have a similar problem. I don't read association view. My code:
void MeterRead() {
uint32_t serverAddress = cl_getServerAddress(1, 1, 2);
DLMS_ERROR_CODE ret;

cl_init(&GxCon.settings, 1, 0x30, serverAddress, DLMS_AUTHENTICATION_HIGH, ADMIN_PASSWORD, DLMS_INTERFACE_TYPE_HDLC);
if (com_initializeConnection(&GxCon) == DLMS_ERROR_CODE_OK) {
gxProfileGeneric Profile;
uint32_t endTime = 1624966136; // Tue Jun 29 2021 11:28:56 GMT+0000
uint32_t startTime = endTime - 12 * 3600; // 12 hours
if (((ret = cosem_init(&Profile.base, DLMS_OBJECT_TYPE_PROFILE_GENERIC, "1.0.99.1.0.255")) == DLMS_ERROR_CODE_OK) &&
((ret = com_read(&GxCon, &Profile.base, 3)) == DLMS_ERROR_CODE_OK) &&
((ret = com_readRowsByRange(&GxCon, &Profile, startTime, endTime)) == DLMS_ERROR_CODE_OK))
{
//
arr_clear(&Profile.captureObjects);
arr_clear(&Profile.buffer);
}
}
if (ret != DLMS_ERROR_CODE_OK) {
PRINT("ERROR %d", ret);
while(1);
}
com_close(&GxCon);
cl_clear(&GxCon.settings);
}

I get "Not enough memory available" at the 15th iteration. What should I free?

Profile picture for user Kurumi

Kurumi

4 years 11 months ago

Hi,

Hi,

Change this line:
arr_clear(&Profile.buffer);
to:
obj_clearProfileGenericBuffer(&Profile.buffer);

arr_clear doesn't clear the content of the array.
BR,
Mikko

Alexander86

4 years 11 months ago

Thanks! It works.

Thanks! It works.

  • Create new account
  • Reset your password

Hire Us!

Latest Releases

  • Tue, 06/09/2026 - 11:16
    gurux.dlms.java 4.0.95
  • Tue, 06/09/2026 - 10:03
    Gurux.DLMS.Python 1.0.199
  • Mon, 06/08/2026 - 13:39
    gurux.dlms.cpp 9.0.2606.0801
  • Mon, 06/01/2026 - 10:15
    gurux.dlms.cpp 9.0.2606.0101
  • Thu, 05/28/2026 - 16:06
    gurux.dlms.java 4.0.94

New forum topics

  • Error reading L&G Meter
  • Pass a TCP Client to GXNet
  • Australian EDMI Mk10D (Essential Energy area)
  • Strange mix of data notificiation vs get response
  • DLMS Connection
More

Who's new

  • Tuanhgg
  • Adel
  • charnon
  • Paddles
  • Miguel Ángel
RSS feed
Privacy FAQ GXDN Issues Contact
Follow Gurux on Twitter Follow Gurux on Linkedin